/**************************************************************************
 * @doc EMV
 * @module EMVSrc |
 * Source code for the EMV handling functions.
 *
 * Product         :   SoftPay 2000 (Global Payment Methodology).
 * <nl>Developer   :   SoftPay Development Team ASPAC ADC.
 * <nl>Notes       :
 *
 * @head3 EMV Functions |
 * @index | EMV
 * @end
 *
 * Copyright (c) 1996-2005 by VeriFone Inc. All rights reserved.
 *
 * No part of this software may be used, stored, compiled, reproduced,
 * modified, transcribed, translated, transmitted, or transferred, in any form
 * or by any means whether electronic, mechanical, magnetic, optical,
 * or otherwise, without the express prior written permission of VeriFone, Inc.
 *
 * Revision History
 * ------------------------------------------------------------------------
 *
 *
 *
 ********************************************************************************/
#ifdef IMAM_LOG
#ifndef LOGSYS_FLAG
#define LOGSYS_FLAG
#endif
#endif

#include <project.h>
#define EMV_C

#include <sizes.h>
#include <aclconio.h>
#include <stdio.h>
#include <stdlib.h>
#include <acldev.h>
#include <aclstr.h>
#include <aclutil.h>
#include <prot8583.h>
#include <define.h>
#include <transact.h>
#include <dbmgr.h>
#include <mdlfuncs.h>
#include <svc.h>
#include <protocol.h>
#include <packet.h>
#include <tran.h>
#include <comm.h>
#include <modem.h>
#include <ppt.h>
#include <piputl.h>
#include <pipmsg.h>
#include <isoutl.h>
#include <isoload.h>
#include <ifldtbl.h>
#include <msg.h>
#include <msgfuncs.h>
#include <bdt.h>
#include <hdt.h>
#include <trt.h>
#include <mht.h>
#include <iit.h>
#include <accum.h>
#include <form.h>
#include <date.h>
#include <mem.h>
#include <spdebug.h>
#include <funcids.h>
#include <pbatch.h>
#include <errno.h>
#include <ascii.h>
#include <amexhost.h>
#include <pct.h>
#include <formater.h>
#include <table.h>
#include <string.h>
#include <confio.h>
#include <aclfile.h>
#include <format.h>
#include <spamsg.h>
#include <oper.h>
#include <batmsg.h>
#include <ui.h>
#include <tct.h>
#include <multilng.h>
#include <logo.h>
#include <settlbat.h>
#include <msgclrk.h>
#include <msgshf.h>
#include <menufunc.h>
#include <mit.h>
#include <applidl.h>
#include <tblutil.h>
#include <menus.h>
#include <Validt.h>
#include <stats.h>
#include <cardmsg.h>
#include <card.h>
#include <msg.h>
#include <define.h>
#include <entry.h>
#include <pinpad.h>
#include <ctype.h>
#include <gds.h>
#include <power.h>
#include <tip.h>
#include <iso8583.h>
#include <beetle.h>
#include <xmodem.h>
#include <modemmsg.h>
//#include <scdefine.h>
#include <rcptsegs.h>
#include <operate.h>

#include <libvoy.h>
#include <cardslot.h>
#include <EMVCWrappers.h>
#include <common.h>
#include <EMVCStructs.h>

#include <vxemvap.h>
#include <emvlib.h>
#include <estfuncs.h>
#include <mvtfuncs.h>
#include <mvt.h>
#include <est.h>
#include <confproto.h>

#include "..\cpacsrc\cpacids.h"
#include "..\cpacsrc\cpacsize.h"
#include "..\cpacsrc\cpacmsg.h"

#include "..\EMVsrc\EMVmsg.h"
#include "..\EMVsrc\EMVsrc.h"
#include "..\EMVsrc\EMVcall.h"
#include "..\EMVsrc\EMVids.h"
#include "..\EMVsrc\EMVsrcdef.h"
#include "..\EMVsrc\EMViso.h"
#include "..\EMVsrc\EMVTC.h" // Added by Thiru for TCUPLOAD Resend

#include "..\..\SOURCE\PRINT\HOSTFORM.H"

byte * pszGlobalIssuerScriptResults;

VS_BOOL fEMVDebugPrint = VS_TRUE; // KK new debug flag
VS_BOOL fEMVDebugDisp = VS_TRUE; // KK new debug flag
VS_BOOL fImamTag5F34Exist = VS_FALSE; // for INT15

unsigned long lnGlobalAmount;
int inGlobalNumberScripts;
long lnTranTitleMessage;
long lnErrorMessage;

extern STATS gsrStats;
extern STATS_REPORT gsrStatsRpt;
extern unsigned char szEMVField55[EMV_FIELD55_SIZE + 1];
extern int pinStatus; //edi -pin
EMV_LOG_REPORT gsrEMVLogRpt;
static char	*pszFilename = "SPSTATS";
static char *STATS_FRM = "STATS.FRM";

extern int pinSigRequired;
extern int inPinTried;
extern unsigned char uchGblPinTryCtr;
extern Menu           *pmeCurrentMenu;

//KiaSoon 03022006 Started: To fix AEIPS APPL SELECT PROBLEM EDR044
extern int inFirstSelect;
extern int inMenuFuncTried;
//KiaSoon 03022006 Ended
/*********************************************************************************************
* @func void | vdAddEMVFunctions |
*       Adds the EMVspecific functions to the function table flexi record.
* @end
**********************************************************************************************/

void vdAddEMVFunctions( void )
{
	inAddMessageFileName( EMV_NAME_ID, "emv");

	inAddFunctionPointer( INIT_EMV,			inEMVAPIInit);
	inAddFunctionPointer( INIT_EMV_DATA,	inEMVAPITransInit);
	inAddFunctionPointer( EMV_CHECK_FALLBACK, inEMVAPICheckFallback);

	inAddFunctionPointer( EMV_REMOVE_CARD,	inEMVAPIRemoveCard);
	inAddFunctionPointer( EMV_PR_AND_TRM,	inEMVAPIPRandTRM);
	inAddFunctionPointer( EMV_CARDHOLDER_VERIF, inEMVAPICardholderVerification);
	inAddFunctionPointer( EMV_FIRST_GEN_AC, inEMVAPIFirstGenerateAC);
	inAddFunctionPointer( EMV_USE_HOST_DATA, inEMVAPIUseHostDataFlow);
	inAddFunctionPointer( EMV_DATA_AUTH, inEMVAPIDataAuthentication);
	inAddFunctionPointer( EMV_SET_OFFLINE, inEMVAPISetOffline);
	inAddFunctionPointer( EMV_GET_BASE_AMOUNT, inEMVAPIGetBaseAmount);
	//inAddFunctionPointer( EMV_BATCH, inEMVAPIPrepareBatch);
	inAddFunctionPointer(EMV_PRINT_LOG_REPORT,  inEMVLogReportOperation);
	inAddFunctionPointer(EMV_DEBUG_PRINT_REPORT,  inEMVDebugPrintReport);
	inAddFunctionPointer(EMV_GET_TERMID, (PFI_TO)inEMVGetTermID);
	inAddFunctionPointer(EMV_GET_USER_PIN, (PFI_TO)inEnterWithMessage);
	inAddFunctionPointer( EMV_SPLIT_SALES, inEMVUpdateSplitSales);
	inAddFunctionPointer(EMV_REFERRAL_PROCESSING, inEMVReferralProcessing);
	inAddFunctionPointer(EMV_FORCE_ONLINE, inEMVForceOnline);
	//inAddFunctionPointer(EMV_CHECK_FORCE_ONLINE, inEMVCheckForceOnline);
	inAddFunctionPointer(EMV_RESET_FORCE_ONLINE_TIME, inEMVResetForceOnlineTime);
	inAddFunctionPointer(EMV_SET_AUTH_FLOOR_LIMIT, inEMVSetAuthFloorLimit);
	inAddFunctionPointer(EMV_ADD_DATA_TO_BATCH, inEMVAddDataToBatch);
	inAddFunctionPointer(EMV_DISPLAY_SIG_REQD,inEMVDisplaySigReqd);
	inAddFunctionPointer(EMV_RESET_FALLBACK_TIME, inEMVResetFallBackTime);
	inAddFunctionPointer(EMV_CHECK_TRANS_ALLWD, inEMVCheckTransAllwd);
	inAddFunctionPointer(EMV_CHECK_FALLBACK_TIME, inEMVCheckFallBackTime);
	inAddFunctionPointer(EMV_CHECK_FORCEONLINE_TIME, inEMVCheckForceOnlineTime);
	inAddFunctionPointer(EMV_SET_NONCHIP, inEMVSetNonChip);
       //inAddFunctionPointer(EMV_PRINT_RECEIPT_TOP, inEMVPrintReceiptTop);

	inOverloadFieldID(CARD_READ_OPERATION, (PFI_TO)inEMVCardReadOperation);
	inOverloadFieldID(VALIDATE_ICC_CARD, inEMVValidateICCCard);
    inOverloadFieldID(DEMO_FUNCTION, inEMVDemo);
    inOverloadFieldID(GET_CARD_FIELDS, inEMVEnterCardData);

}

/****************************************/
/* Function that called by other Softpay function */
/* But it is part of the transaction flow 		       */
/****************************************/
int inEMVCardReadOperation (TRANSACTION_OBJECT *pobTran, PFI_TO pinValSwiped, int *pinResult)
{

	int inAmtInputLine;  // inStatus,   ICC_LINT_REMOVED
	char	szNull[21 + 1];//, szICCMessage [MESSAGE_SIZE + 1]
	PFI_TO pinMyFn;  //1.4 modified to PFI_TO

		if (getgrid() == 0) inAmtInputLine = 3;
		else inAmtInputLine = 7;

		memset (szNull, NULL_CH, sizeof (szNull));

		#ifdef VXEMVAPP
		if(inVXEMVAPCardPresent() == SUCCESS)
		{
			if(inRunFunction(pobTran, EMV_CHECK_TRANS_ALLWD) == VS_ERR)
					return VS_ERR;
		}
		#endif /* VXEMVAPP */
LOG_PRINTFF((0x8L,"inEMVCardReadOperation"));
		*pinResult = pinValSwiped(pobTran);

		if (*pinResult == VS_SUCCESS)
		{
			if ((inGetPrinterType() == NOPRINTER  || !fGetEnablePrinter()) &&
				(pobTran->srBRec.inTranCardType == DEBIT_CARD ||
				pobTran->srBRec.inTranCardType == EBT_CARD))
			{
				vdDisplayMessageFromFile( TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
				return(VS_ERR);
			}
#ifdef IMAM_DBS
			if ((pinMyFn = inGetFunctionPointer(DISPLAY_SWIPE_CARD_INFO)) == NULL_PFI)
				return(VS_ERR);

			if (pinMyFn(pobTran) == VS_ERR) return (VS_ERR);
#endif
		}
		else
		{

			if (lnGGErrorMessage())
            {
            		#ifdef VXEMVAPP
            			if(lnGGErrorMessage() == EMV_FAILURE_MSG21)
            			{
            				vdSGErrorMessage(0L);
            				return VS_ERR;
            			}
            		#endif /* VXEMVAPP */

				vdDisplayMessageFromFile( lnGGErrorMessage(), WARNING_MSG);
				if (obDisp.inTitleLine == obDisp.inStatusLine || obDisp.inTitleLine == obDisp.inInputLine)
               {
					clrscr();
               }
               if (obDisp.inTerminalType == TERMINAL_OMNI_3200)
               {
					char szNull[21 + 1];

                        memset(szNull, NULL_CH, sizeof(szNull));
						if ((getgrid() == 0) && (get_font_mode() == 2)) // 2 byte addressing scheme + 16x16 Font
						{
							szNull[0] = 0x01;
							szNull[1] = 0x20;
						}
						else {
							szNull[0] = SPACE;
						}
                        /* remove previous prompts so not scrolled after error */
                        vdDisplayAt(obDisp.inHomeCol, (inAmtInputLine - 1), szNull, CLR_EOL);
                        vdDisplayAt(obDisp.inHomeCol, inAmtInputLine, szNull, CLR_EOL);
                        vdDisplayAt(obDisp.inHomeCol, obDisp.inCharsPerColumn,
                                    szNull, CLR_EOL);
                }

			   vdSGErrorMessage(0L);   /* Do not want to display this again */

               return(VS_ERR);
            }

			// if you have error message active
                /* Clear Track Data on bad reads */
            memset(pobTran->srBRec.stT1Data, 0, TRACK1_SIZE);/* Clear Track 1  */
            memset(pobTran->srBRec.stT2Data, 0, TRACK2_SIZE);/* Clear Track 2  */
			strcpy(pobTran->srBRec.szCHolder, szNull);
        }


		return (VS_SUCCESS);
}

#if 0
int inEMVEnterCardData (TRANSACTION_OBJECT *pobTran)
{
char	szNull[21 + 1];
int		inResult = VS_ERR, inStatus;
unsigned long	ulTimerCount;
PFI		pinValSwiped, pinValManual;
#ifdef ICC_DEFINED
PFI		pinValICC;
#endif


PFI_TO_PFI_PIN		pinTempFn;
PFI_TO_PSZ_F	pinGetCardBin;
struct	TRACK srCardData;


#ifdef	COUNTER_DEFINED
		COUNTER_OBJECT	obCounter;

		obCounter.inIndex = ALL_RECORDS;
#endif

	//pdebug(("--inEnterCardData--"));

	BT_TRACE ('I', "Account #:");

if (strlen(pobTran->srBRec.szPAN) > 0)
{

	if ((pinGetCardBin = inGetFunctionPointer(GET_CARD_BIN)) == NULL_PFI)
    {
		/**/pdebug (("inGetFunctionPointer pinValSwiped Error"));/**/
        return(VS_ERR);
    }

	inResult = pinGetCardBin(pobTran, pobTran->srBRec.szPAN, VS_TRUE );
	if (inResult == VS_SUCCESS)
		vdDetermineCardType(pobTran, &srCardData);					/* Card Detection */
	return(inResult);

}
	// sets up the Menu
	if ( inRunFunction (pobTran, START_CARD_TRAN) == VS_ERR )
	{
		return (VS_ERR);
	}

	if ((pinValSwiped = inGetFunctionPointer(VALIDATE_SWIPED_CARD)) == NULL_PFI)
	{
		//pdebug (("inGetFunctionPointer pinValSwiped Error"));
		return(VS_ERR);
	}

	if ((pinValManual = inGetFunctionPointer(VALIDATE_MANUAL_NO)) == NULL_PFI)
	{
		//pdebug (("inGetFunctionPointer pinValManual Error"));
		return(VS_ERR);
	}
#ifdef ICC_DEFINED
	if ((pinValICC = inGetFunctionPointer(VALIDATE_ICC_CARD)) == NULL_PFI)
	{
		//pdebug (("inGetFunctionPointer pinValManual Error"));
		return(VS_ERR);
	}
	if (inVXEMVAPCardPresent() != SUCCESS)
	    pobTran->inChipStatus = NOT_USING_CHIP;
	#endif
	memset(szNull, NULL_CH, (int)sizeof(szNull));

    ulTimerCount = set_itimeout(NO_CLOCK_HANDLE inGetIdleTimeOut(), TM_SECONDS);

	do
	{
		if (CHK_CARD_RDR())
		{
			if ((pinTempFn = inGetFunctionPointer(CARD_READ_OPERATION)) == NULL_PFI)
				return(VS_ERR);
#ifdef COUNTER_DEFINED
			if (pinTempFn(pobTran, pinValSwiped, &inResult) == VS_ERR)
			{
				obCounter.inType = CARD_READ_ERROR;
				inIncCounter(&obCounter, 1);
				return (VS_ERR);
			}
			else
			{
				obCounter.inType = CARD_READ_ATTEMPTED;
				inIncCounter(&obCounter, 1);
			}
#else
			if (pinTempFn(pobTran, pinValSwiped, &inResult) == VS_ERR)
				return (VS_ERR);
#endif	/* COUNTER_DEFINED */

			#ifdef VXEMVAPP

			//Check if the swiped card is a chip card
			if((pobTran->szServiceCode[0] == '2') || (pobTran->szServiceCode[0] == '6'))
			{

				if(inEMVGetICCReadFailure() == VS_FALSE)
				{
					vdDisplayMessageFromFile(EMV_USE_CHIP_READER, ERROR_MSG);
					vdSGErrorMessage(0L);
					return(VS_ERR);
				}
			}
			#endif /* VXEMVAPP */
		}
#ifdef ICC_DEFINED
        else if ((inVXEMVAPCardPresent() == SUCCESS) && (pobTran->inChipStatus == NOT_USING_CHIP))
        {

            if ((pinTempFn = inGetFunctionPointer(CARD_READ_OPERATION)) == NULL_PFI)
                return(VS_ERR);
            if (pinTempFn(pobTran, pinValICC, &inResult) == VS_ERR)
                return(VS_ERR);
        	pobTran->srBRec.inChipStatus = pobTran->inChipStatus;
    		vdDetermineCardType(pobTran, &srCardData);					/* Card Detection */
        }
#endif
		else if (act_kbd_pending_test(KEY_CANCEL))
		{
			inResult = VS_ESCAPE;
		}
		else if (KBHIT())
		{
			if ((pinTempFn = inGetFunctionPointer(MANUAL_ENTRY_PROCESS)) == NULL_PFI)
				return(VS_ERR);
			inStatus = pinTempFn(pobTran, pinValManual, &inResult);
			if ( inStatus < 0) return (inStatus);
		}

		else if (CHECK_TIMEOUT(ulTimerCount) == 0)
		{
			// KV1 20010118 - Allow terminal to go to sleep
	    	if ( srGDS.fHandHeld && srGDS.fBatteryOperated && get_dock_status () == HANDHELD_UNDOCKED )
			{
				vdTerminalSleep ();
			}
			else
			{
				inResult = VS_ESCAPE;
			}
		}
		/*
		 *		Allow additional custom Card Entry
		 */
		else
		{
			inResult = inRunFunction (pobTran, CHECK_CARD_ENTRY);
		}
	} while (inResult == VS_ERR);

	vdFlushKeyboardBuffer();

	if (inResult >= 0)
	{
		inResult = VS_SUCCESS;
		if ( inRunFunction (pobTran, DISPLAY_CARD_TITLE) == VS_ERR )
			return (VS_ERR);
	}

    vdClrNextLineEntry(); /* turn off */

	//pdebug(("--EXIT inEnterCarddata--"));
	return(inResult);
}
#endif

int inEMVEnterCardData (TRANSACTION_OBJECT *pobTran)
{
char	szNull[21 + 1];
int		inResult = VS_ERR, inStatus;
unsigned long	ulTimerCount;
PFI		pinValSwiped, pinValManual;
#ifdef ICC_DEFINED
PFI		pinValICC;
#endif


PFI_TO_PFI_PIN		pinTempFn;
PFI_TO_PSZ_F	pinGetCardBin;
struct	TRACK srCardData;
	char chEnableEMV = 0; //Renu 18022005 Converted to a global variable

#ifdef	COUNTER_DEFINED
		COUNTER_OBJECT	obCounter;

		obCounter.inIndex = ALL_RECORDS;
#endif

	//pdebug(("--inEnterCardData--"));

	BT_TRACE ('I', "Account #:");

	get_env("EMV.ALLOWED", (char*)&chEnableEMV, 1); //Getting the value once during cold init
if (strlen(pobTran->srBRec.szPAN) > 0)
{

	if ((pinGetCardBin = inGetFunctionPointer(GET_CARD_BIN)) == NULL_PFI)
    {
		/**/pdebug (("inGetFunctionPointer pinValSwiped Error"));/**/
        return(VS_ERR);
    }

	inResult = pinGetCardBin(pobTran, pobTran->srBRec.szPAN, VS_TRUE );
	if (inResult == VS_SUCCESS)
		vdDetermineCardType(pobTran, &srCardData);					/* Card Detection */
	return(inResult);

}
	// sets up the Menu
	if ( inRunFunction (pobTran, START_CARD_TRAN) == VS_ERR )
	{
		return (VS_ERR);
	}

	if ((pinValSwiped = inGetFunctionPointer(VALIDATE_SWIPED_CARD)) == NULL_PFI)
	{
		//pdebug (("inGetFunctionPointer pinValSwiped Error"));
		return(VS_ERR);
	}

	if ((pinValManual = inGetFunctionPointer(VALIDATE_MANUAL_NO)) == NULL_PFI)
	{
		//pdebug (("inGetFunctionPointer pinValManual Error"));
		return(VS_ERR);
	}
#ifdef ICC_DEFINED
	if ((pinValICC = inGetFunctionPointer(VALIDATE_ICC_CARD)) == NULL_PFI)
	{
		//pdebug (("inGetFunctionPointer pinValManual Error"));
		return(VS_ERR);
	}
	if (inVXEMVAPCardPresent() != SUCCESS)
	    pobTran->inChipStatus = NOT_USING_CHIP;
	#endif
/************************************ To disable EMV transactions **********************************************/
		if(inVXEMVAPCardPresent() == SUCCESS)
		{
			if(chEnableEMV == '0')
			{
				vdDisplayMessageFromFile(TRANS_NOT_SUPPORTED_MSG, WARNING_MSG);
				return VS_ERR;
			}
		}
/************************************ To disable EMV transactions **********************************************/
	memset(szNull, NULL_CH, (int)sizeof(szNull));

    ulTimerCount = set_itimeout(NO_CLOCK_HANDLE inGetIdleTimeOut(), TM_SECONDS);

		do
		{
			if (CHK_CARD_RDR())
			{
			if ((pinTempFn = inGetFunctionPointer(CARD_READ_OPERATION)) == NULL_PFI)
				return(VS_ERR);
#ifdef COUNTER_DEFINED
			if (pinTempFn(pobTran, pinValSwiped, &inResult) == VS_ERR)
			{
				obCounter.inType = CARD_READ_ERROR;
				inIncCounter(&obCounter, 1);
				return (VS_ERR);
			}
			else
			{
				obCounter.inType = CARD_READ_ATTEMPTED;
				inIncCounter(&obCounter, 1);
			}
#else
			if (pinTempFn(pobTran, pinValSwiped, &inResult) == VS_ERR)
				return (VS_ERR);
#endif	/* COUNTER_DEFINED */

			#ifdef VXEMVAPP
			//Check if the swiped card is a chip card
			//To skip Service code checking

			if (fGetChkServiceCode())
			{



				if((pobTran->szServiceCode[0] == '2') || (pobTran->szServiceCode[0] == '6'))
				{


					if(inEMVGetICCReadFailure() == VS_FALSE)
					{

						vdDisplayMessageFromFile(EMV_USE_CHIP_READER, ERROR_MSG);
						vdSGErrorMessage(0L);
						return(VS_ERR);
					}
				}
			}
			#endif /* VXEMVAPP */
		}
#ifdef ICC_DEFINED
        else if ((inVXEMVAPCardPresent() == SUCCESS) && (pobTran->inChipStatus == NOT_USING_CHIP))
        {
/************************************ To disable EMV transactions **********************************************/
	            if(chEnableEMV != '0')
	            {

		            if ((pinTempFn = inGetFunctionPointer(CARD_READ_OPERATION)) == NULL_PFI)
		                return(VS_ERR);
		            if (pinTempFn(pobTran, pinValICC, &inResult) == VS_ERR)
		                return(VS_ERR);
		        	pobTran->srBRec.inChipStatus = pobTran->inChipStatus;
		    		vdDetermineCardType(pobTran, &srCardData);					/* Card Detection */
	            	}
			else
			{
				vdDisplayMessageFromFile(TRANS_NOT_SUPPORTED_MSG, WARNING_MSG);
				return VS_ERR;
			}
		}
/************************************ To disable EMV transactions **********************************************/
#endif
			else if (act_kbd_pending_test(KEY_CANCEL))
			{
				inResult = VS_ESCAPE;
			}
			else if (KBHIT())
			{
				if ((pinTempFn = inGetFunctionPointer(MANUAL_ENTRY_PROCESS)) == NULL_PFI)
					return(VS_ERR);
				inStatus = pinTempFn(pobTran, pinValManual, &inResult);
				if ( inStatus < 0) return (inStatus);
			}

			else if (CHECK_TIMEOUT(ulTimerCount) == 0)
			{
				// KV1 20010118 - Allow terminal to go to sleep
		    	if ( srGDS.fHandHeld && srGDS.fBatteryOperated && get_dock_status () == HANDHELD_UNDOCKED )
				{
					vdTerminalSleep ();
				}
				else
				{
					inResult = VS_ESCAPE;
				}
			}
			/*
			 *		Allow additional custom Card Entry
			 */
			else
			{
				inResult = inRunFunction (pobTran, CHECK_CARD_ENTRY);
			}
		} while (inResult == VS_ERR);

		vdFlushKeyboardBuffer();

		if (inResult >= 0)
		{
			inResult = VS_SUCCESS;
			if ( inRunFunction (pobTran, DISPLAY_CARD_TITLE) == VS_ERR )
				return (VS_ERR);
		}

    vdClrNextLineEntry(); /* turn off */

	//pdebug(("--EXIT inEnterCarddata--"));
	return(inResult);
}

int inEMVValidateICCCard (TRANSACTION_OBJECT *pobTran)
{
    	//byte transType;
    	unsigned char ucTransType;
    	short autoFlag;
    	unsigned short usResult;
	int result;
	PFI		pinGetCardBin;
	unsigned short	inDOLen;
	char	szTmpPAN[PAN_SIZE+1];
	char	szTmpExpDate[6+1];		// in ASCII
	char	szTmpStartDate[6+1];	// in ASCII
	char	szTrack2Data[40+1];		// in ASCII
	char buffer[11+1];
	char szMessage[MESSAGE_SIZE + 1];
	int  inImamNoChipError = 0;

	BYTE	btPAN[20];
	BYTE	btExpDate[3];
	BYTE	btStartDate[3];
	BYTE	btSvcCode[2];
	BYTE	ptPANSeq[1];
	BYTE	btCardholder[26];
	BYTE	btTrack2[20];

	

char	szTmpServiceCode[4+1];	// in ASCII
int i;

	int inResult;
	char szCurrentDate[10];

int  mvtCount, emvCounter;  // YL 20060407 SiangThye email counter reset counter

	srAIDListStatus srTermAIDListStatus[MAX_AID_LIST];
	//srAIDListStatus srTempAIDListStatus[MAX_AID_LIST]; //KiaSoon: AEIPS DR044
	unsigned short aidCount;
	unsigned short blockAidCount;
	
	LOG_PRINTFF((0x08L, "VALIDATE_ICC_CARD = inEMVValidateICCCard ============="));

	memset(szMessage, 0x00, sizeof(szMessage));

	vdClearNonTitleLines();
    	vdDisplayMessageFromFile( EMV_PROCESSING_MSG21, STATUS_MSG);

/*
	{ // reenable this..?
		if (pobTran->inTransactionCode == SALE || pobTran->inTransactionCode == AUTH_ONLY || pobTran->inTransactionCode == IMAM_CARDVER) {
			transType = 0x00; //SALE transtype for EMVAPP module
		}
		usEMVAddTLVToCollxn(0x9c00, (byte *) &transType, 1);
	}
*/
	pobTran->inChipStatus = EMV_CARD;

	LOG_PRINTFF((0x08L, "API: inVXEMVAPCardInit========="));
	result = inVXEMVAPCardInit();
/*//////////////////////////
////////////////////////////
LIEM : Original
  	if (result != SUCCESS) {
        if (result == CHIP_ERROR){ //Changed from EMV_CHIP_ERROR as this value is returned from emv lib
			vdDisplayWarningString("CHIP NOT DETECTED");
			inWaitKey(inGetIdleTimeOut());
			vdScrollDataEntry(VS_TRUE);
			vdSGErrorMessage(EMV_REINSERT_CARD_MSG);
			return VS_ERR;
        } else {
			vdPromptManager((unsigned short)result);
    		vdSGErrorMessage(CARDREAD_ERR_MSG);
        }
    	//inEMVAPIRemoveCard(pobTran);
        //return (result);
        return (VS_ERROR);
    }
*/ 
////////////////////////////////
{//: the replacement
	if (result != SUCCESS) {
        if (result == CHIP_ERROR) {	// Set chip failure flag
			LOG_PRINTFF((0x08L, "API: inVXEMVAPCardInit ======== RetVal = %d [CHIP_ERROR]", result));
			inImamNoChipError = 1;
			//vdEMVSetICCReadFailure(VS_TRUE);
            //vdDisplayFallbackMsg(pobTran);
			//inVXEMVAPRemoveCard(vdPromptRemoveManager);
        } else if (result == NO_ATR) {
            LOG_PRINTFF((0x08L, "API: inVXEMVAPCardInit ======== RetVal = %d [NO_ATR]", result));
			vdSGErrorMessage(CARDREAD_ERR_MSG);
		}else {
			LOG_PRINTFF((0x08L, "API: inVXEMVAPCardInit ======== RetVal = %d [OTHER ERROR]", result));
    		vdSGErrorMessage(CARDREAD_ERR_MSG);
		}
	} else {
		LOG_PRINTFF((0x08L, "API: inVXEMVAPCardInit ======== RetVal = %d [OK]", result));
	}
}//////////////////////////////////

  	//Set the transaction type
	if (pobTran->srBRec.lnBaseTransactionAmount > 0)
	{

		if (pobTran->srBRec.lnCashBackAmount > 0)
			ucTransType = CASHBACK_TRAN;
		else
			ucTransType = GOODS_SERVICES_TRAN;
	}
	else if ((pobTran->srBRec.lnCashBackAmount > 0) || (pobTran->srTRTRec.TransactionCode == CASH_ADV))
		ucTransType = CASH_TRAN;
	else
		ucTransType = GOODS_SERVICES_TRAN;	// Default if no amounts supplied - situation
									// should not arise!

	usResult = usEMVAddTLVToCollxn(TAG_9C00_TRAN_TYPE, (byte *)&ucTransType, 1);
	LOG_PRINTFF((0x08L, "TAG(0x%X): EMVAddTLV [TAG_9C00_TRAN_TYPE = 0x%X]", TAG_9C00_TRAN_TYPE, ucTransType));
	if (usResult != EMV_SUCCESS)
	return (VS_ERR);


	//Get the Terminal Serial Number and add to the EMV collection Object
	//Required for Master card
/*
	{  // Add for BNI
		char chImamBuffer[128];
		int  inResult;
		int  i;

		memset(chImamBuffer, 0x00, sizeof(chImamBuffer));
		inResult = SVC_INFO_SERLNO(chImamBuffer);
		if (inResult) {
			memset(chImamBuffer, 0x00, sizeof(chImamBuffer));
  			inResult = get_env("TERMSERNUM", chImamBuffer, sizeof(chImamBuffer));
			if(inResult <= 0) {
       			strcpy(chImamBuffer, "10102397");
			}
		}
		for (i=0; i<strlen(chImamBuffer); i++) {
			if (!isdigit(chImamBuffer[i])) {
				strcpy(&chImamBuffer[i], &chImamBuffer[i+1]);
				i--;
			}
		}
		if (strlen(chImamBuffer)>8) {
			strcpy(chImamBuffer, &chImamBuffer[strlen(chImamBuffer)-8]);
		}
		LOG_PRINTFF((0x08L, "EDC SN : [%s]", chImamBuffer));

		//Permata Req : EDCDIC for Visa, Ascii for MasterCard. //BNI: req Ascii
		//for (i=0; i<strlen(chImamBuffer); i++) { chImamBuffer[i] = chImamBuffer[i] + 192; } //make it EBCDIC

    	usEMVAddTLVToCollxn(TAG_9F1E_IFD_SER_NUM , (byte *)chImamBuffer, strlen(chImamBuffer));
		LOG_PRINTFF((0x08L, "TAG(0x%X): EMVAddTLV [TAG_9F1E_IFD_SER_NUM = %s]", TAG_9F1E_IFD_SER_NUM, chImamBuffer));
		
	}  //end of add
*/
/*
	{
  		result = get_env("TERMSERNUM", buffer, sizeof(buffer));
		if(result <= 0)
       		memcpy(buffer, "10102397", sizeof(buffer));
		else
			SVC_INFO_SERLNO(buffer);  //jrd 05212005
		usEMVAddTLVToCollxn(TAG_9F1E_IFD_SER_NUM , (byte *)buffer, strlen(buffer));
	}
*/	
	autoFlag = inGetAutoSelectApplnFlag();
	
	LOG_PRINTFF((0x08L, "API: inVXEMVAPSelectApplication ========="));
	result = inVXEMVAPSelectApplication(autoFlag, inMenuFunc, vdPromptManager, usAmtEntryFunc, NULL);
	LOG_PRINTFF((0x08L, "API: inVXEMVAPSelectApplication ======== RetVal = %d [OK]", result));

	/* KiaSoon 03022006 Started: Fixed AEIPS Problem EDR-044*/
	inMenuFuncTried=0; 
 	while((result == TRANS_CANCELLED) && (inFirstSelect!=2))
 	{
		LOG_PRINTFF((0x08L, "API: inVXEMVAPSelectApplication ======== RetVal = %d [TRANS_CANCELLED]", result));
		LOG_PRINTFF((0x08L, "RETRY...Selection"));
 		inRunFunction(pobTran, INIT_EMV_DATA);
 		pobTran->inChipStatus = EMV_CARD;	
 		inVXEMVAPCardInit();
 		usResult = usEMVAddTLVToCollxn(TAG_9C00_TRAN_TYPE, (byte *)&ucTransType, 1);
		LOG_PRINTFF((0x08L, "TAG(0x%X): EMVAddTLV [TAG_9C00_TRAN_TYPE = 0x%X]", TAG_9C00_TRAN_TYPE, ucTransType));
 		usEMVAddTLVToCollxn(TAG_9F1E_IFD_SER_NUM , (byte *)buffer, strlen(buffer));
		LOG_PRINTFF((0x08L, "TAG(0x%X): EMVAddTLV [TAG_9F1E_IFD_SER_NUM = %s]", TAG_9F1E_IFD_SER_NUM, buffer));
 		result = inVXEMVAPSelectApplication(autoFlag, inMenuFunc, vdPromptManager, usAmtEntryFunc, NULL);
 		inMenuFuncTried=0;
 	}
 		
 	vdResetApplLabel(); 
 	// KiaSoon 03022006 Ended
 	
 	if (result != SUCCESS) {
        LOG_PRINTFF((0x8L,"-- After VXEMVAPSelectApplication but fail"));
		//To find if there are any blocked applications in the card
        usEMVGetAllAIDStatus(srTermAIDListStatus, &aidCount, &blockAidCount);	
		if(blockAidCount >= 1){
			LOG_PRINTFF((0x08L, "API: inVXEMVAPSelectApplication ======== RetVal = %d [APPL_BLOCKED?]", result));
			vdPromptManager((unsigned short)APPL_BLOCKED);
			if(inVXEMVAPCardPresent() == SUCCESS) {
    			vdSGErrorMessage(EMV_PLS_REMOVE_CARD_MSG);
				//inVXEMVAPRemoveCard(vdPromptRemoveManager); //
    		} else {
				vdSGErrorMessage(EMV_FAILURE_MSG21);
			}
			//vdSGErrorMessage(CARDREAD_ERR_MSG);
			return VS_ERR;
		}
        if ((result == CHIP_ERROR) || (result == APPL_NOT_AVAILABLE) || (result == EMV_FAILURE)|| (result == CANDIDATELIST_EMPTY)) {			
			if (result == CHIP_ERROR){
				LOG_PRINTFF((0x08L, "API: inVXEMVAPSelectApplication ======== RetVal = %d [CHIP_ERROR]", result));
			} else if (result == APPL_NOT_AVAILABLE){
				LOG_PRINTFF((0x08L, "API: inVXEMVAPSelectApplication ======== RetVal = %d [APPL_NOT_AVAILABLE]", result));
			} else if (result == EMV_FAILURE){
				LOG_PRINTFF((0x08L, "API: inVXEMVAPSelectApplication ======== RetVal = %d [EMV_FAILURE]", result));
			} else if (result == CANDIDATELIST_EMPTY){
				LOG_PRINTFF((0x08L, "API: inVXEMVAPSelectApplication ======== RetVal = %d [CANDIDATELIST_EMPTY]", result));
			}
			// Set chip failure flag
			vdEMVSetICCReadFailure(VS_TRUE);
			//TO DO FALLBACK PROCESSING HERE
			//vdDisplayFallbackMsg(pobTran);
			//inRunFunction (pobTran, EMV_CHECK_FALLBACK);
			vdPromptManager((unsigned short)result);
			if  (inGetFallbackAllowedFlag()) {
				if (inImamNoChipError==1 && inImamEMVFullFallback()==0){
					vdSGErrorMessage(EMV_REINSERT_CARD_MSG);
				} else {
					vdSGErrorMessage(EMV_USE_MAG_STRIPE);
					vdEMVSetFallbackTime(); //To set timer for the chip card to be swiped
				}
			} else {
			    vdSGErrorMessage(EMV_FAILURE_MSG21);
			}
			//Remove the card
			//inVXEMVAPRemoveCard(vdPromptRemoveManager);
			/*
			if(inVXEMVAPCardPresent() == SUCCESS)
				vdSGErrorMessage(EMV_PLS_REMOVE_CARD_MSG);
			else
				vdSGErrorMessage(EMV_FAILURE_MSG21);
			*/
			inWaitKey(inGetIdleTimeOut()); //
			return VS_ERR;
		} else {
			LOG_PRINTFF((0x08L, "API: inVXEMVAPSelectApplication ======== RetVal = %d [OTHER ERROR]", result));
			vdPromptManager((unsigned short)result);
			if(inVXEMVAPCardPresent() == SUCCESS) {
    			vdSGErrorMessage(EMV_PLS_REMOVE_CARD_MSG);
			} else {
				vdSGErrorMessage(EMV_FAILURE_MSG21);
			}
        }
    	//inEMVAPIRemoveCard(pobTran);
        //return (result);
        return(VS_ERR);
    }
	{
		int inImamResult = -1;
		LOG_PRINTFF((0x08L, "API: inVXEMVAPGetCardConfig ======== "));
		inImamResult = inVXEMVAPGetCardConfig(-1,-1 );
		LOG_PRINTFF((0x08L, "API: inVXEMVAPGetCardConfig ======== RetVal = %d", inImamResult));
	}

	// Read application data from card
	LOG_PRINTFF((0x08L, "API: inVXEMVAPProcessAFL ======== "));
	result = inVXEMVAPProcessAFL();
    if (result != SUCCESS) {
    	if (result == CHIP_ERROR) {
			LOG_PRINTFF((0x08L, "API: inVXEMVAPProcessAFL ======== RetVal = %d [CHIP_ERROR]", result));
			// Set chip failure flag
			vdEMVSetICCReadFailure(VS_TRUE);
			//vdDisplayFallbackMsg(pobTran);
			vdPromptManager((unsigned short)result);
			if  (inGetFallbackAllowedFlag()) {
			    vdSGErrorMessage(EMV_USE_MAG_STRIPE);
				//To set timer for the chip card to be swiped
				vdEMVSetFallbackTime();
			} else { 
				vdSGErrorMessage(EMV_FAILURE_MSG21);
			}
			//if(inVXEMVAPCardPresent() == SUCCESS)
			//vdSGErrorMessage(EMV_PLS_REMOVE_CARD_MSG);
			return(VS_ERR);
        }
		LOG_PRINTFF((0x08L, "API: inVXEMVAPProcessAFL ======== RetVal = %d [OTHER ERROR]", result));
    	vdPromptManager((unsigned short)result);
    	if(inVXEMVAPCardPresent() == SUCCESS) {
    		vdSGErrorMessage(EMV_PLS_REMOVE_CARD_MSG);
    	} else {
			vdSGErrorMessage(EMV_FAILURE_MSG21);
		}
    	//inEMVAPIRemoveCard(pobTran);
        //return (result);
        return(VS_ERR);
    } else {
		LOG_PRINTFF((0x08L, "API: inVXEMVAPProcessAFL ======== RetVal = %d [OK]", result));
	}

	//[1172] SOFTPAY:F:emvsrc.c|L:00965|API: inVXEMVAPProcessAFL ======== RetVal = 39321 [OTHER ERROR] = 0x9999
	//#define     EMV_FAILURE                     (Ushort)0x9999 

	// Counter should be incremented each time a chip card is read
	// inIncEMVCounter ();  // YL 20060407 SiangThye email start
	// Remark this function, it is causing the EMV counter in mvt.dat to be incremented twice
	
	mvtCount = inGetMVTRecNumber();
	emvCounter = ulGetEMVCounter();
	if ((emvCounter > 32766))
	{
		inLoadMVTRec(0);
		emvCounter = 1;
		vdSetEMVCounter(emvCounter);
		inSaveMVTRec(0);
		inLoadMVTRec(mvtCount);
	} // YL 20060407 SiangThye email end
	{// Get Track 2 Equivalent Data in BCD
		char buff[256];
		memset(buff, 0x00, sizeof(buff));
		usResult = usEMVGetTLVFromColxn(TAG_57_TRACK2_EQ_DATA, (byte *)btTrack2, (unsigned short *) &inDOLen);
		if (inDOLen<128) hex_2_asc((BYTE *)buff, btTrack2, inDOLen);
		LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[TAG_57_TRACK2_EQ_DATA = %s]", TAG_57_TRACK2_EQ_DATA, buff));
	}
															
	if (usResult == EMV_SUCCESS && inDOLen)	// If Track 2 Equivalent Data exists
	{
		hex_2_asc((BYTE *)szTrack2Data, btTrack2, inDOLen);	// Convert it to a NULL-terminated ASCII string

		for (i=0; i < (2*inDOLen); i++)
		{
			if (szTrack2Data[i] == 'F')
			{
				szTrack2Data[i] = 0;
				break;
			}

			if (szTrack2Data[i] == 'D')		// Field separator
			{
				szTrack2Data[i] = '=';		// Relace with field separator expected by SoftPay
			}
		}

		strcpy(pobTran->srBRec.stT2Data, szTrack2Data);		// Store Track 2
   		pobTran->srBRec.fT2Data = VS_TRUE;
	}
	{
		char buff[256];
		memset(buff, 0x00, sizeof(buff));
		usResult = usEMVGetTLVFromColxn(TAG_5A_APPL_PAN, (byte *)btPAN, (unsigned short *) &inDOLen);	// Get PAN, remember it's in BCD
		if (inDOLen<128) hex_2_asc((BYTE *)buff, btPAN, inDOLen);
		LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[TAG_5A_APPL_PAN = %s]", TAG_5A_APPL_PAN, buff));
	}

	if (usResult == EMV_SUCCESS)
	{
	memset(szTmpPAN, 0, sizeof(szTmpPAN));
    	hex_2_asc((BYTE *)szTmpPAN, btPAN, inDOLen);		// Convert it to a NULL-terminated string
	    // Could be an 'F' on the end of string, so get rid of it

    	while (szTmpPAN[strlen(szTmpPAN) - 1] == 'F')
    		szTmpPAN[strlen(szTmpPAN) - 1] = 0;

     	strcpy(pobTran->srBRec.szPAN, szTmpPAN);

        pobTran->srBKey.lnLast4 = str2long (&pobTran->srBRec.szPAN[strlen(pobTran->srBRec.szPAN) - LAST4_DIGIT_ACCT]);
    }


//jrd spqalog071 & SPQALog098
if ((strncmp(szTmpPAN,  szTrack2Data, strlen(szTmpPAN)) != 0)  && (strncmp(szTmpPAN,  "3", 1) != 0))
{
	// Set chip failure flag
	vdEMVSetICCReadFailure(VS_TRUE);

	//TO DO FALLBACK PROCESSING HERE
	if  (inGetFallbackAllowedFlag())
	{
	    vdSGErrorMessage(EMV_USE_MAG_STRIPE);
		//To set timer for the chip card to be swiped
		vdEMVSetFallbackTime();
	}
	else
	    vdSGErrorMessage(EMV_FAILURE_MSG21);

	return(VS_ERR);
}
//jrd spqalog071

	{
		char buff[256];
		memset(buff, 0x00, sizeof(buff));
		usResult = usEMVGetTLVFromColxn(TAG_5F24_EXPIRY_DATE, (byte *)btExpDate, (unsigned short *) &inDOLen);	// Get Expiry Date
		if (inDOLen<128) hex_2_asc((BYTE *)buff, btExpDate, inDOLen);
		LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[TAG_5F24_EXPIRY_DATE = %s]", TAG_5F24_EXPIRY_DATE, buff));
	}

	if (usResult == EMV_SUCCESS)
	{
    	hex_2_asc((BYTE *)szTmpExpDate, btExpDate, inDOLen);	// Convert it to a NULL-terminated string (YYMMDD)

	    strncpy(pobTran->srBRec.szExpDate, szTmpExpDate, 4);
    	pobTran->srBRec.szExpDate[4] = 0;					// Only want YYMM
    }

#if 0
	vdGetDate(szCurrentDate, YYMM);
	szTmpExpDate[4]=0x00;
	szCurrentDate[4]=0x00;
	if(atol(szTmpExpDate) <= atol(szCurrentDate)) //albert_d1 08182005 check expiry date
	{
		vdDisplayErrorMessage(EXP_CARD_ERR_MSG21);
		if(inVXEMVAPCardPresent() == SUCCESS)
				inVXEMVAPRemoveCard(vdPromptRemoveManager);
		return(VS_ERR);
	}

#endif

	/*	inResult = inValidateExpDate(pobTran->srBRec.szExpDate);

			if (inResult != VS_SUCCESS)
			{

				if(inVXEMVAPCardPresent() == SUCCESS)
				{

					inVXEMVAPRemoveCard(vdPromptRemoveManager);
				}
				return(inResult);
			}
	*/

	{
		char buff[256];
		memset(buff, 0x00, sizeof(buff));
		usResult = usEMVGetTLVFromColxn(TAG_5F25_EFFECT_DATE, (byte *)btStartDate, (unsigned short *) &inDOLen);	// Get Start Date
		if (inDOLen<128) hex_2_asc((BYTE *)buff, btStartDate, inDOLen);
		LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[TAG_5F25_EFFECT_DATE = %s]", TAG_5F25_EFFECT_DATE, buff));
	}

	if (usResult == EMV_SUCCESS && inDOLen)	// If start date exists
	{
		hex_2_asc((BYTE *)szTmpStartDate, btStartDate, inDOLen);	// Convert it to a NULL-terminated string (YYMMDD)
		strncpy(pobTran->srBRec.szStartDate, szTmpStartDate, 4);
		pobTran->srBRec.szStartDate[4] = 0;	  			// Only want YYMM
	}

	vdGetDate(szCurrentDate, YYMM);
	szTmpStartDate[4]=0x00;

	if(atol(szTmpStartDate) > atol(szCurrentDate)) //albert_d1 08182005 check effectivity date
	{
		vdDisplayErrorMessage(EMV_NOT_YET_EFFECTIVE_MSG);
		if(inVXEMVAPCardPresent() == SUCCESS)
					inVXEMVAPRemoveCard(vdPromptRemoveManager);
		return(VS_ERR);
	}

	{
		char buff[256];
		memset(buff, 0x00, sizeof(buff));
		usResult = usEMVGetTLVFromColxn(TAG_5F34_APPL_PAN_SEQNUM, (byte *)ptPANSeq, (unsigned short *) &inDOLen);
		if (inDOLen<128) hex_2_asc((BYTE *)buff, ptPANSeq, inDOLen);
		LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[TAG_5F34_APPL_PAN_SEQNUM = %s]", TAG_5F34_APPL_PAN_SEQNUM, buff));
	}														
	// Get Issuer Number, i.e. PAN Sequence Number
	if (usResult == EMV_SUCCESS && inDOLen)	// If Issuer Number exists
	{
		hex_2_asc((BYTE *)pobTran->srBRec.szIssueNumber, ptPANSeq, inDOLen);	// Convert it to a NULL-terminated string (YYMMDD)
		LOG_PRINTFF((0x08L, "TAG_5F34_APPL_PAN_SEQNUM = [%s]", pobTran->srBRec.szIssueNumber));
		fImamTag5F34Exist = VS_TRUE;
	} else {
		LOG_PRINTFF((0x08L, "TAG_5F34_APPL_PAN_SEQNUM = [NOT EXIST]"));
		fImamTag5F34Exist = VS_FALSE;
	}

	{
		char buff[256];
		memset(buff, 0x00, sizeof(buff));
		usResult = usEMVGetTLVFromColxn(TAG_5F30_SERVICE_CODE, (byte *)btSvcCode, (unsigned short *) &inDOLen);	// Get Service Code
		if (inDOLen<128) hex_2_asc((BYTE *)buff, btSvcCode, inDOLen);
		LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[TAG_5F30_SERVICE_CODE = %s]", TAG_5F30_SERVICE_CODE, buff));
	}
	if (usResult == EMV_SUCCESS && inDOLen)	// If service Code exists
	{
		hex_2_asc((BYTE *)szTmpServiceCode, btSvcCode, inDOLen);	// Convert it to a NULL-terminated string (YYMMDD)
		strcpy(pobTran->szServiceCode, szTmpServiceCode+1);
	}

	usResult = usEMVGetTLVFromColxn(TAG_5F20_CARDHOLDER_NAME, (byte *)btCardholder, (unsigned short *) &inDOLen);	// Get Card Holder Name
	LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[TAG_5F20_CARDHOLDER_NAME = %s]", TAG_5F20_CARDHOLDER_NAME, btCardholder));
	if (usResult == EMV_SUCCESS && inDOLen)	// If service Code exists
	{

		strncpy(pobTran->srBRec.szCHolder, (char *)btCardholder, inDOLen);
		pobTran->srBRec.szCHolder[inDOLen] = 0;		// Null terminate
		pobTran->srBRec.fCHolder = VS_TRUE;
	}


	//To clear the application name form the screen
	vdClearTitleLine();
	vdGetMessageFromFile(lnTranTitleMessage , szMessage);
	vdDisplayAt(1, 1, szMessage, NO_CLEAR);


	#if 0
	memset(btAPPLPrefName, 0x00,20);
       memset(btAppName, 0x00,20);

	usEMVGetTLVFromColxn(TAG_9F12_APPL_PRE_NAME, (byte *)btAPPLPrefName, (unsigned short *) &inDOLen);
	usEMVGetTLVFromColxn(TAG_50_APPL_LABEL, (byte *)btAppName, (unsigned short *) &inDOLen);
	vdDisplayAt(1, 3,"APP NAME:", NO_CLEAR);
	 if(  memcmp((char*)btAPPLPrefName,"CREDITO DE VISA",15) == 0 )
        {

		vdDispStrAtRight((char*)btAPPLPrefName, 5, NO_CLEAR);


        }
	 else
	 {

		vdDispStrAtRight((char*)btAppName, 5, NO_CLEAR);
	 }

	do
	{
		memset(btAppName, 0x00,20);
		usEMVGetTLVFromColxn((const Ushort)inttag, (byte *)btAppName, (unsigned short *) &inDOLen);

		inttag++;

	}
	while(inttag ==5000);

	//usResult = usEMVGetTLVFromColxn(TAG_50_APPL_LABEL, btAppName, (unsigned short *) &inDOLen);
	//usResult = usEMVGetTLVFromColxn(TAG_84_DF_NAME, btAppName, (unsigned short *) &inDOLen);

	usResult = usEMVGetTLVFromColxn(TAG_9F12_APPL_PRE_NAME, (byte *)btAppName, (unsigned short *) &inDOLen);
	if (usResult == EMV_SUCCESS && inDOLen)	// If service Code exists
	{

		strncpy(szAppName, (char *)btCardholder, inDOLen);
		szAppName[inDOLen] = 0;		// Null terminate


		vdDisplayAt(1, 3,"APP NAME:", NO_CLEAR);
		vdDisplayAt(1, 4,(const char*)szAppName, NO_CLEAR);
 	}



	usResult = usEMVGetTLVFromColxn(TAG_50_APPL_LABEL, (byte *)btAppName, (unsigned short *) &inDOLen);
	if (usResult == EMV_SUCCESS && inDOLen)	// If service Code exists
	{

		strncpy(szAppName, (char *)btCardholder, inDOLen);
		szAppName[inDOLen] = 0;		// Null terminate


		vdDisplayAt(1, 3,"APP NAME:", NO_CLEAR);
		vdDisplayAt(1, 4,(const char*)szAppName, NO_CLEAR);
 	}

	if(  memcmp((char*)btAPPLPrefName,"CREDITO DE VISA",15) == 0 )
        {
            vdSetCardLabel((char*)btAPPLPrefName);
        }
	    else
	    {
            vdSetCardLabel((char*)btAPPLLabel);
	    }

#endif

    	if ((pinGetCardBin = inGetFunctionPointer(GET_CARD_BIN)) == NULL_PFI)
    	{
		/*pdebug (("inGetFunctionPointer pinValSwiped Error")); */
        	return(VS_ERR);
    	}

	pobTran->srBRec.fManual = VS_FALSE;
	LOG_PRINTFF((0x08L, "GET_CARD_BIN called in part of VALIDATE_ICC_CARD"));
	result = pinGetCardBin (pobTran, szTmpPAN, VS_FALSE);
	if (result < 0)
	{
		INCREMENT_CARD_ERROR;
		vdSGErrorMessage(CARDREAD_ERR_MSG);
		return (result);
	}
	LOG_PRINTFF((0x08L, "VALIDATE_ICC_CARD = inEMVValidateICCCard ============= VALIDATE_ICC_CARD"));
	return (VS_SUCCESS);
}

int inEMVDemo(TRANSACTION_OBJECT *pobTran)
{
	//byte		issAuthData[28];
	//unsigned short issAuthDataLen;
	//unsigned short usRetVal;

    if (pobTran->inEMVCardDecision == EMV_GO_ONLINE)
    {

    /*issAuthData[0] = 0x11;
    issAuthData[1] = 0x22;
    issAuthData[2] = 0x33;
    issAuthData[3] = 0x44;
    issAuthData[4] = 0x55;
    issAuthData[5] = 0x66;
    issAuthData[6] = 0x77;
    issAuthData[7] = 0x88;
    issAuthData[8] = 0x99;*/

    /*issAuthData[0] =0xFC;
    issAuthData[1] = 0x29;
    issAuthData[2] = 0x0B;
    issAuthData[3] = 0x6E;
    issAuthData[4] = 0x0C;
    issAuthData[5] = 0x79;
    issAuthData[6] = 0xF6;
    issAuthData[7] = 0x30;
    issAuthData[8] = 0x30;
    issAuthData[9] = 0x30;*/



    //issAuthDataLen = 9;

    //usRetVal = usEMVUpdateTLVInCollxn(TAG_91_ISS_AUTH_DATA,issAuthData,issAuthDataLen);
    //if (usRetVal != EMV_SUCCESS)
       //return(VS_ERR);

    usEMVUpdateTLVInCollxn(TAG_8A_AUTH_RESP_CODE , (byte*)"00", 2);
	LOG_PRINTFF((0x08L, "TAG(0x%X): EMVUpdateTLV[TAG_8A_AUTH_RESP_CODE = 00]", TAG_8A_AUTH_RESP_CODE));

    /*
    script1[0] = 0x71;
    script1[1] = 0x0E;
    script1[2] = 0x9F;
    script1[3] = 0x18;
    script1[4] = 0x04;
    script1[5] = 0;
    script1[6] = 0;
    script1[7] = 0;
    script1[8] = 0;
    script1[9] = 0x86;
    script1[10] = 0x05;
    script1[11] = 0x00;
    script1[12] = 0x84;
    script1[13] = 0x00;
    script1[14] = 0x00;
    script1[15] = 0x00;

    usEMVUpdateTLVInCollxn(TAG_ISUER_SCRPT_TEMPL_71,&script1[2],script1[1]);

    script2[0] = 0x72;
    script2[1] = 0x0E;
    script2[2] = 0x9F;
    script2[3] = 0x18;
    script2[4] = 0x04;
    script2[5] = 0;
    script2[6] = 0;
    script2[7] = 0;
    script2[8] = 0;
    script2[9] = 0x86;
    script2[10] = 0x05;
    script2[11] = 0x80;
    script2[12] = 0xCA;
    script2[13] = 0x9F;
    script2[14] = 0x36;
    script2[15] = 0x00;

    usEMVUpdateTLVInCollxn(TAG_ISUER_SCRPT_TEMPL_72,&script2[2],script2[1]);
    */
	pobTran->srBRec.inTransactionResult = AUTHORIZED;
    }
    return(VS_SUCCESS);
}


/*******************************/
/* EMV operation flow function */
/*******************************/
int inEMVAPIInit(TRANSACTION_OBJECT *pobTran)
{
	vdEMVSetFallbackToMSR(VS_FALSE);

	inApplnESTVerifyAllCAPKs(); // Added to

    	inVXEMVAPSCInit();

    	return (VS_SUCCESS);
}

int inEMVAPITransInit(TRANSACTION_OBJECT *pobTran)
{
	int	inResult;
	int inTerminalRecord=0;		//default zero for first record
	PFI_PSZ pinGetTID;

	LOG_PRINTFF((0x08L, "INIT_EMV_DATA = inEMVAPITransInit ===================="));
	inPinTried = 0; // A flag to differentiate between first pin try and retries
	uchGblPinTryCtr = 0;

	// Get the Terminal ID
	if ((pinGetTID = inGetFunctionPointer(EMV_GET_TERMID)) == NULL_PFI)
	{
		pinGetTID= inDefaultGetPTID; //default function pointer is szGetPTID
	}

	if ((inResult = inVXEMVAPTransInit(inTerminalRecord,pinGetTID)) != SUCCESS)
	{
        	return (inResult);
	}

	pobTran->inChipStatus = NOT_USING_CHIP;	// Default value of chip status flag
    	pobTran->inIssuerMVTIndex = EMV_TABLE_NOT_USED;
   	pobTran->inAcquirerMVTIndex = EMV_TABLE_NOT_USED;

	LOG_PRINTFF((0x08L, "INIT_EMV_DATA = inEMVAPITransInit =================== INIT_EMV_DATA"));

	return(VS_SUCCESS);
}

int inEMVAPICheckFallback(TRANSACTION_OBJECT *pobTran)
{
	int inResult;

	//Check if same chip card is being swiped by having a timeout value
	char szCurrTime[TIME_SIZE + 1];
	char szFallBackTime[TIME_SIZE + 1];
	char szFallBackTimeOut[TIME_SIZE + 1];

	int inFallBackTimeOut, inTimeDiff;

	LOG_PRINTFF((0x08L, ""));

	memset(szCurrTime, 0x00, sizeof(szCurrTime));
	memset(szFallBackTime, 0x00, sizeof(szFallBackTime));
	memset(szFallBackTimeOut, 0x00, sizeof(szFallBackTimeOut));

	pobTran->inFallbackAllowed = VS_FALSE;



	if (fGetChkServiceCode())
	{


		if((pobTran->inChipStatus != EMV_CARD) &&
			((pobTran->szServiceCode[0] == '2') || (pobTran->szServiceCode[0] == '6')))
		{
			
			if(inLoadTCTRec(0) != VS_SUCCESS)
			{
			 	vdDisplayMessageFromFile(TCT_ERR_MSG21, ERROR_MSG);
			 	return VS_ERR;
			}

			strcpy(szFallBackTime, szGetFallBackTime());

			if(strlen(szFallBackTime) > 0)
			{
				
				vdGetTime(szCurrTime);
				inTimeDiff = inEMVGetTimeDiff(szCurrTime, szFallBackTime);

				get_env("EMV.TIMEOUT", szFallBackTimeOut, sizeof(szFallBackTimeOut));
				inFallBackTimeOut = atoi(szFallBackTimeOut);

				if(inTimeDiff > inFallBackTimeOut)
					return VS_ERR;
			}
			else
			{
	
				vdDisplayMessageFromFile(EMV_USE_CHIP_READER, ERROR_MSG);
				vdSGErrorMessage(0L);
				return(VS_ERR);
			}


			//inResult = inVXEMVAPCheckFallback(pobTran->szServiceCode, inDisplayOverrideChipScrn, vdPromptManager);
			inResult = inVXEMVAPCheckFallback(pobTran->szServiceCode, NULL, vdPromptManager);

			if(inResult != SUCCESS)
			{

				pobTran->srBRec.inTransactionResult = CANCELLED;
		   		pobTran->srBKey.fVoided = VS_TRUE;
		   		return (VS_ERR);
			}

			pobTran->inFallbackAllowed = VS_TRUE;
		}
	}

	return(VS_SUCCESS);
}

/*********************************/
/* EMV transaction flow function */
/*********************************/
int inEMVAPIRemoveCard(TRANSACTION_OBJECT *pobTran)
{
   	//if (pobTran->srBRec.inChipStatus == EMV_CARD)
   	//KiaSoon 150206: Add in for refund and sales offline
	char buff[256];

   	if ((pobTran->inChipStatus == EMV_CARD) || (pobTran->inChipStatus == EMV_EASY_ENTRY_CARD))
	{


		if (!inVXEMVAPCardPresent())
		{

			#if VISA_DEBUG
				usEMVGetTLVFromColxn(TAG_9500_TVR, (byte *)&stBufTVR, &LenTVR);
				memset(buff, 0x00, sizeof(buff));
				if (LenTVR<128) hex_2_asc((BYTE *)buff, stBufTVR, LenTVR);
				LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[TAG_9500_TVR = %s]", TAG_9500_TVR, buff));

				usEMVGetTLVFromColxn(TAG_9B00_TSI, (byte *)&stBufTSI, &LenTSI);
				memset(buff, 0x00, sizeof(buff));
				if (LenTSI<128) hex_2_asc((BYTE *)buff, stBufTSI, LenTSI);
				LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[TAG_9B00_TSI = %s]", TAG_9B00_TSI, buff));

				strcpy((char*) szTempTVRBuf, (char*) "TVR:  ");
				strcpy((char*) szTempTSIBuf, (char*) "TSI:  ");
				hex_2_asc (&szTempTVRBuf[5], stBufTVR, 5);
				hex_2_asc (&szTempTSIBuf[5], stBufTSI, 2);
				vdDisplayAt (1, 3, (char*) szTempTVRBuf, NO_CLEAR);
				vdDisplayAt (1, 4, (char*) szTempTSIBuf, NO_CLEAR);
			#endif

			vdClearNonTitleLines ();

			inVXEMVAPRemoveCard(vdPromptRemoveManager);

			while (!inVXEMVAPCardPresent()); //Looping until the card removed.

			vdEMVSetICCReadFailure(VS_FALSE);
		}
	}


    	return(VS_SUCCESS);
}

int inEMVAPIPRandTRM(TRANSACTION_OBJECT *pobTran)
{
	int inResult;
	srTxnResult srTvrTsi;
	char floor_limit[10];

	memset(floor_limit,0x00,sizeof(floor_limit));
	LOG_PRINTFF((0x08L, "EMV_PR_AND_TRM = inEMVAPIPRandTRM =============================="));
	//usEMVGetTxnStatus(&srTvrTsi);
	if (pobTran->inChipStatus == EMV_CARD)
	{
		 LOG_PRINTFF((0x08L, "API: inVXEMVAPProcRisk ================="));
		 inResult = inVXEMVAPProcRisk(bIsCardBlackListed);
		 LOG_PRINTFF((0x08L, "API: inVXEMVAPProcRisk ================= RetVal=[%d]", inResult));
		 if (inResult != SUCCESS)
		 {
		 	usEMVGetTxnStatus(&srTvrTsi);
		 	vdPromptManager((unsigned short)inResult);

			if (inResult == CHIP_ERROR)
			{	// Set chip failure flag (chip failure is possible for DDA)
				vdEMVSetICCReadFailure(VS_TRUE);
			}
			return(VS_ERR);
		 }

		 /////////edi - Interoper 27///////////////
		    	usEMVGetTxnStatus(&srTvrTsi);
		    	if(!(srTvrTsi.stTSI[0] & 0x08)) {			//Cek TRM di set atau gak
				//read floor limit, jika amount lebih besar > floor limit , set TVR floor limt exceeded
				get_env_x("EMV.FLOORLIMIT", 0, floor_limit);
				if(atol(floor_limit) < pobTran->srBKey.lnTotalOfTransactionAmount){
				    srTvrTsi.stTVR[3] |= 0x80; // floor limit exceeded
				    srTvrTsi.stTSI[0] |= 0x08;	//Terminal risk management was performed				
				}
		    	}
			usEMVSetTxnStatus(&srTvrTsi);
		/////////////////////////////////////////////
	}
	//usEMVGetTxnStatus(&srTvrTsi);
	LOG_PRINTFF((0x08L, "EMV_PR_AND_TRM = inEMVAPIPRandTRM ============================== OK"));
    return(VS_SUCCESS);
}

int inEMVAPICardholderVerification(TRANSACTION_OBJECT *pobTran)
{
	int inResult;
	int inSignatureRequired;
	//srTxnResult srTvrTsi;
	unsigned char szCVMResults[10+1];
	unsigned char szTempBuf[10+1];
	unsigned short tagLen;
	char buff[256];

	LOG_PRINTFF((0x08L, "EMV_CARDHOLDER_VERIF = inEMVAPICardholderVerification =========="));
	memset(szCVMResults, 0x00, sizeof(szCVMResults));
	memset(szTempBuf, 0x00, sizeof(szTempBuf));

	inSignatureRequired = VS_TRUE; //Initialize the value

	//usEMVGetTxnStatus(&srTvrTsi);
	if (pobTran->inChipStatus == EMV_CARD)
	{
		pinStatus = -1;
		 LOG_PRINTFF((0x08L, "API: inVXEMVAPVerifyCardholder ================="));
		 inResult = inVXEMVAPVerifyCardholder(NULL);
		 LOG_PRINTFF((0x08L, "API: inVXEMVAPVerifyCardholder ================= RetVal=[%d]", inResult));

	    if (inResult != SUCCESS)
		{
			vdPromptManager((unsigned short)inResult);

			if (inResult == CHIP_ERROR)
			{	// Set chip failure flag (chip failure is possible for DDA)
				vdEMVSetICCReadFailure(VS_TRUE);
			}

			return(VS_ERR);
		}
		
		//edi - cek pin
		if(pinStatus == E_USR_PIN_CANCELLED) return (VS_ERR);
		//For debug purpose...to be removed
		usEMVGetTLVFromColxn(TAG_9F34_CVM_RESULTS,(byte*) &szTempBuf, &tagLen);
		memset(buff, 0x00, sizeof(buff));
		if (tagLen<128) hex_2_asc((BYTE *)buff, szTempBuf, tagLen);
		LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[TAG_9F34_CVM_RESULTS = %s]", TAG_9F34_CVM_RESULTS, buff));

		SVC_HEX_2_DSP((char*)szTempBuf, (char*)szCVMResults, 3);
		inStoreBatchFieldData(&pobTran->srBRec, CITI_EMV_CVM_RESULTS, (unsigned char *)szCVMResults, 6);
		LOG_PRINTF(("CVM Results = %s", szCVMResults));

		vdClearASCII8x21Window(1, 7, 21, 8);

		//usEMVGetTxnStatus(&srTvrTsi);
	      /*  if (pinSigRequired)
	            vdSetCDTSignLine (1);
	        else
	            vdSetCDTSignLine (0);*/
	}

	LOG_PRINTFF((0x08L, "EMV_CARDHOLDER_VERIF = inEMVAPICardholderVerification ========== OK"));
    return(VS_SUCCESS);
}

int inEMVAPIFirstGenerateAC(TRANSACTION_OBJECT *pobTran)
{
	srTxnResult srTvrTsi;
	unsigned short Len = 1;
	unsigned short usTVRLen = 1;
	unsigned char flag = 0x00;
	int  inResult;
	unsigned short usResult;
	unsigned short usRetVal;
	//int  inTermDecision = 0;	// Terminal decision about online/offline
	unsigned short tagLen;
	byte cryptInfoData;
	byte buf[2];
	char szRID[EMV_RID_SIZE + 1];
	//KiaSoon 070206: for Receipt APPL CRYTO Printing
	unsigned char bTagOutput[255];
	int inOffset = 0;
	//KiaSoon Ended;			
	char buff[256];

	memset(szRID, 0x00, sizeof(szRID));
	LOG_PRINTFF((0x08L, "EMV_FIRST_GEN_AC = inEMVAPIFirstGenerateAC ====================="));
	if (pobTran->inChipStatus == EMV_CARD) {
		//Reset the global error message variable
		lnErrorMessage = 0L;
		pobTran->fReferral = VS_FALSE;
		pobTran->inEMVTermDecision = inGetTerminalDecision();
		//LOG_PRINTF(("In first gen ac 1"));
		LOG_PRINTFF((0x08L, "API: inVXEMVAPFirstGenerateAC ==============="));
		inResult = inVXEMVAPFirstGenerateAC(pobTran->inEMVTermDecision);
		LOG_PRINTFF((0x08L, "API: inVXEMVAPFirstGenerateAC =============== RetVal=[%d]", inResult));
		if (inResult != SUCCESS) {
			//If Master/EuroPay card allow fallback for response 6985
		    szGetESTRID(szRID);
			if ((strncmp(szRID, "A000000004", 10) == 0) || (strncmp(szRID, "A000000010", 10) == 0)) {
				if(inResult == USE_MAG_CARD) {
					//Do fallback processing
					vdEMVSetICCReadFailure(VS_TRUE);
					//vdDisplayFallbackMsg(pobTran);
					vdPromptManager((unsigned short)inResult);
					if  (inGetFallbackAllowedFlag()){
			    		vdSGErrorMessage(EMV_USE_MAG_STRIPE);
						//To set timer for the chip card to be swiped
						vdEMVSetFallbackTime();
					} else {
			    		vdSGErrorMessage(EMV_FAILURE_MSG21);
					}
					//Remove the card
					/*
					if(inVXEMVAPCardPresent() == SUCCESS)
						inVXEMVAPRemoveCard(vdPromptRemoveManager);
					else
						vdSGErrorMessage(EMV_FAILURE_MSG21);
					*/
				}
			} else {
				inResult = EMV_FAILURE;
				vdPromptManager(inResult);
				if(inVXEMVAPCardPresent() == SUCCESS) {
					inVXEMVAPRemoveCard(vdPromptRemoveManager);
				}
			}
			return VS_ERR;
		}
		//LOG_PRINTF(("In first gen ac 2"));
	   	// Make decision based on cryptogram information data returned by ICC
		usResult = usEMVGetTLVFromColxn(0x9f27, &cryptInfoData, &tagLen);
		memset(buff, 0x00, sizeof(buff));
		LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[??? = 0x%X] /cryptogram information data returned by ICC", 0x9f27, cryptInfoData));
	   	if (usResult != EMV_SUCCESS) {
	       	return (usResult);
		}
    	usEMVGetTLVFromColxn(TAG_8A_AUTH_RESP_CODE , buf, &tagLen);
		memset(buff, 0x00, sizeof(buff));
		if (tagLen<128) hex_2_asc((BYTE *)buff, buf, tagLen);
		LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[TAG_8A_AUTH_RESP_CODE = %s]", TAG_8A_AUTH_RESP_CODE, buff));	

		//AAC requested, CID doesn't matter //to make sure card is not tampered
   	 	if(memcmp(buf, AAC_GEN1AC_DECLINE, 2)==0) {
   	 		pobTran->inEMVCardDecision = EMV_DECLINE;
			pobTran->srBRec.inTransactionResult = DECLINED;
			strlcpy(pobTran->srBRec.szAuthCode, AAC_GEN1AC_DECLINE, RESP_CODE_SIZE);
			vdSGErrorMessage(EMV_DECLINE_MSG21);
			return (VS_ERROR);
        		//return(OFFLINE_DECLINED);
   	 	}
	    	
		switch(cryptInfoData & 0xC0) {
		    case 0: //Declined --- AAC
		    	if((cryptInfoData & 0xC7) == 0x01){		//Service not allowed
		    		vdClearNonTitleLines();
		    		vdSGErrorMessage(EMV_NOT_ACCEPTED_MSG);
					vdSGRespMsg("");
	    			//inEMVAPIRemoveCard(pobTran);
	    			pobTran->srBRec.inTransactionResult = CANCELLED;
					return (VS_ERROR);
		    	} else {
		    		pobTran->inEMVCardDecision = EMV_DECLINE;
					pobTran->srBRec.inTransactionResult = DECLINED;
					strlcpy(pobTran->srBRec.szAuthCode, AAC_GEN1AC_DECLINE, RESP_CODE_SIZE);	 // KK added
					vdSGErrorMessage(EMV_DECLINE_MSG21);
					vdSGRespMsg("");
					return (VS_ERROR);
		    	}
		    case 0x40: //Offline Approval --- TC
		    	pobTran->inEMVCardDecision = EMV_OFFLINE_AUTH;
		        pobTran->srBRec.inTransactionResult = AUTHORIZED;
	            //strcpy(srRcpt.szErrorMessage, "EMV AUTHORISED");
	            usRetVal = usEMVUpdateTLVInCollxn(TAG_8A_AUTH_RESP_CODE , (byte *)TC_GEN1AC_APPROVE, 2);
				LOG_PRINTFF((0x08L, "TAG(0x%X): EMVUpdateTLV[TAG_8A_AUTH_RESP_CODE = 00]", TAG_8A_AUTH_RESP_CODE, TC_GEN1AC_APPROVE));		
   				if (usRetVal != EMV_SUCCESS)
    		    	return(VS_ERR);
            	strcpy(pobTran->srBRec.szAuthCode, TC_GEN1AC_APPROVE);
            	pobTran->srTRTRec.Offline = VS_TRUE;		
            	//KiaSoon Started 060206: Avoid print AAC or ARQC on the receipt 
				inOffset = inMakeEMVBatchData(TAG_9500_TVR, (unsigned char*) bTagOutput);
				inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_95_TVR_LEN_2ND, (unsigned char*)&inOffset, sizeof(int));
				inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_95_TVR_2ND,  bTagOutput, inOffset);

				inOffset = inMakeEMVBatchData(TAG_9F26_APPL_CRYPTOGRAM, (unsigned char*) bTagOutput);
				inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F26_APP_CRYPTOGRAM_LEN_2ND, (unsigned char*)&inOffset, sizeof(int));
				inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F26_APP_CRYPTOGRAM_2ND,  bTagOutput, inOffset);
				//KiaSoon 060206: Ended	
            	return VS_SUCCESS;

				#if 0
				//Store this transaction as an offline sale/refund transaction and trickle feed it to the host
				//if(pobTran->srTRTRec.TransactionCode == SALE)
				//{
            				inLoadTRTRec(pobTran, SALE_OFFLINE);
            				vdSGCode(SALE_OFFLINE);
            				pobTran->srTRTRec.TransactionCode = SALE_OFFLINE;
	            			pobTran->srBRec.lnMessage = SALE_OFFLINE_MSG;
				//}
				//else if(pobTran->srTRTRec.TransactionCode == REFUND)
				//{
					//inLoadTRTRec(pobTran, REFUND);
					//vdSGCode(REFUND);
				//}


            			if( inResult = inRunFunction(pobTran, EMV_ADD_DATA_TO_BATCH) != VS_SUCCESS)
				{
					return(VS_ERR);
				}
            			if( inResult = inRunFunction(pobTran, BUILD_AND_SEND_PACKET) != VS_SUCCESS)  //LIEM: NOT USED
				{
					return(VS_ERR);
				}
            			if( inResult = inRunFunction(pobTran, EMV_RESET_FORCE_ONLINE_TIME) != VS_SUCCESS)
				{
					return(VS_ERR);
				}
            			if( inResult = inRunFunction(pobTran, EMV_USE_HOST_DATA) != VS_SUCCESS)
				{
					return(VS_ERR);
				}
            			if(inResult = inRunFunction(pobTran, CPAC_DISPLAY_RESPONSE) != VS_SUCCESS)
            			{
            				return VS_ERR;
            			}
            			if( inResult = inRunFunction(pobTran, UPDATE_BATCH) != VS_SUCCESS)
				{
					return(VS_ERR);
				}
            			if( inResult = inRunFunction(pobTran, UPDATE_ACCUM) != VS_SUCCESS)
				{
					return(VS_ERR);
				}
            			if( inResult = inRunFunction(pobTran, UPDATE_TERM_INV_AND_HOST_INV) != VS_SUCCESS)
				{
					return(VS_ERR);
				}
            			if( inResult = inRunFunction(pobTran, EMV_DISPLAY_SIG_REQD) != VS_SUCCESS)
            			{
            				return VS_ERR;
            			}
				if( inResult = inRunFunction(pobTran, CITI_PRINT_RECEIPT) != VS_SUCCESS)
				{
					return(VS_ERR);
				}
            			if( inResult = inRunFunction(pobTran, EMV_SPLIT_SALES) != VS_SUCCESS)
				{
					return(VS_ERR);
				}
            			if( inResult = inRunFunction(pobTran, EMV_REMOVE_CARD) != VS_SUCCESS)
				{
					return(VS_ERR);
				}

            			return VS_ERR;
            			#endif /* 0 */

		    case 0xC0: //Referral --- AAR  //Do referral processsing here
		    	LOG_PRINTF(("1st GEN AC Referal********"));
		    	usEMVGetTxnStatus(&srTvrTsi);
		    	if(!(srTvrTsi.stTVR[3] & 0x08)) {			//forced on-line
		    		pobTran->inEMVCardDecision = EMV_VOICE_REFERRAL;	
					//pobTran->srBRec.inTransactionResult = CARD_REFERRAL;
					inEMVReferralProcessing(pobTran);
		        	break;
		    	}
		    case 0x80: //ON_LINE --- ARQC
		    	pobTran->inEMVCardDecision = EMV_GO_ONLINE;
				vdSetOffline(pobTran, VS_FALSE);
				break;
    	}
    }

	LOG_PRINTF(("In first gen ac 3"));
	LOG_PRINTF(("MAX HEAP   = %ld.", _heap_max()));
	LOG_PRINTFF((0x08L, "EMV_FIRST_GEN_AC = inEMVAPIFirstGenerateAC ===================== OK"));
    return(VS_SUCCESS);
}


int inEMVAPIUseHostDataFlow(TRANSACTION_OBJECT *pobTran)
{
	int  inLenIAD = 0;
	int  inLenICCData = 0;
	int  inLenScript = 0;
	int  inHostDecision;
	byte btCID;					// Cryptogram Identifier
	unsigned short tagLen;
	int inResult;
	char szMessage[MESSAGE_SIZE + 1];

	//byte resp[MAX_MESSAGE_SIZE];        // Authorisation response message
	int inNumScripts = 0;
	char szRID[EMV_RID_SIZE + 1];

	int inOffset = 0;
	unsigned char bTagOutput[255];
	char buff[256];

	TRANSACTION_OBJECT pobTmpTran;

	LOG_PRINTFF((0x08L, "EMV_USE_HOST_DATA = inEMVAPIUseHostDataFlow ===================="));

	memset(szRID, 0x00, sizeof(szRID));
	memset(szMessage, 0x00, sizeof(szMessage));

	_remove("script71.dat");
   	_remove("script72.dat");
	
	if(pobTran->srBRec.inChipStatus == EMV_CARD) {
		if(pobTran->inEMVCardDecision == EMV_OFFLINE_AUTH) {
			return VS_SUCCESS;
		}
		switch(pobTran->srBRec.inTransactionResult) {
			case AUTHORIZED:
				inHostDecision = HOST_AUTHORISED;
				break;
			case HOST_DECLINED:
				inHostDecision = HOST_DECLINED;
				break;
			case FAILED_TO_CONNECT:
				inHostDecision = FAILED_TO_CONNECT;
				break;
			case HOST_REFERRAL:
				LOG_PRINTF(("2st GEN AC Referal***********"));
				/* Thiru Commented just to delay the referral processing since it goes for 2nd GEN AC */
//				inEMVReferralProcessing(pobTran);
				//if((pobTran->srBRec.inTransactionResult == HOST_AUTHORISED))   
				//	inHostDecision = HOST_AUTHORISED;
				//else if((pobTran->srBRec.inTransactionResult == HOST_DECLINED) ||(pobTran->srBRec.inTransactionResult = HOST_REFERRAL))  
				// KiaSoon: For call referral, try to request AAC
				inHostDecision = HOST_DECLINED;
				break;
			default:
				break;
		}
		// jrd 09272005
		LOG_PRINTFF((0x08L, "Calling... inEMVGetIssuerDataFromResponse(pobTran)"));
		inEMVGetIssuerDataFromResponse(pobTran);
		//Need to allocate memory to script results else will crash when passed to Toolkit
		inNumScripts = inGlobalNumberScripts;
		LOG_PRINTFF((0x08L, "inNumScripts = [%d]", inNumScripts));
		pszGlobalIssuerScriptResults = (byte *) malloc(inNumScripts * 5);
		LOG_PRINTFF((0x08L, "API: inVXEMVAPUseHostData ==================="));
		inResult = inVXEMVAPUseHostData(inHostDecision, pszGlobalIssuerScriptResults, &inNumScripts);
		LOG_PRINTFF((0x08L, "API: inVXEMVAPUseHostData =================== RetVal=[%d]", inResult));
		/* Thiru Commented just to delay the referral processing since it goes for 2nd GEN AC */
		LOG_PRINTFF((0x08L, "Calling... inEMVReferralProcessing(pobTran)"));
		inEMVReferralProcessing(pobTran);

		//jrd for saving and printing the final TVR
		inOffset = inMakeEMVBatchData(TAG_9500_TVR, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_95_TVR_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_95_TVR,  bTagOutput, inOffset);
		//Store the Issuer script results
		if (pszGlobalIssuerScriptResults) {
//			inOffset = (unsigned short)pszGlobalIssuerScriptResults;
//			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_ISSUER_SCRIPT_RESULTS_LEN, (unsigned char*)&inOffset, sizeof(int));
//			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_ISSUER_SCRIPT_RESULTS, (unsigned char*)(pszGlobalIssuerScriptResults + 1), (unsigned short)inOffset);
			//added by Thiru
			inOffset=inNumScripts*5;
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_ISSUER_SCRIPT_RESULTS_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_ISSUER_SCRIPT_RESULTS, (unsigned char*)(pszGlobalIssuerScriptResults), (unsigned short)inOffset);
		}
		if (inResult == SUCCESS) {
			/* this handles the bank referral of EMV*/
			if (((inHostDecision == FAILED_TO_CONNECT) ||(pobTran->fReferral == VS_TRUE)) &&
				((pobTran->srTRTRec.TransactionCode == SALE) || (pobTran->srTRTRec.TransactionCode == REFUND))) {
				//KiaSoon Started 060206: Avoid print AAC on the receipt for call referral
				int ACLen=0;
				int TVRLen=0;
				char btAP[10];
				char btTVR[10];
				
				ACLen = inGetDataLengthFromBatch(pobTran, FID_EMV_TAG_9F26_APP_CRYPTOGRAM_LEN);
				inGetDataFromBatchToEMVPacket(pobTran, FID_EMV_TAG_9F26_APP_CRYPTOGRAM, ACLen, (unsigned char *)&btAP[0]);
				
				TVRLen = inGetDataLengthFromBatch(pobTran, FID_EMV_TAG_95_TVR_LEN);
		 		inGetDataFromBatchToEMVPacket(pobTran, FID_EMV_TAG_95_TVR, TVRLen, (unsigned char *)&btTVR[0]);	
		 				
		 		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_95_TVR_LEN_2ND, (unsigned char*)&TVRLen, sizeof(int));
				inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_95_TVR_2ND,  (unsigned char *)btTVR, TVRLen);
				inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F26_APP_CRYPTOGRAM_LEN_2ND, (unsigned char*)&ACLen, sizeof(int));
				inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F26_APP_CRYPTOGRAM_2ND,  (unsigned char *)btAP, ACLen);
				
				//KiaSoon 060206: Ended	
				//Store this transaction as an offline sale/refund transaction and trickle feed it to the host
				if(pobTran->srTRTRec.TransactionCode == SALE) {
					inLoadTRTRec(pobTran, SALE_OFFLINE);
					vdSGCode(SALE_OFFLINE);
	            	pobTran->srTRTRec.TransactionCode = SALE_OFFLINE;
					//pobTran->srBRec.lnMessage = SALE_OFFLINE_MSG;
					pobTran->srTRTRec.Offline= VS_TRUE;
					pobTran->srBKey.fOffline= VS_TRUE;
	            	pobTran->srBRec.lnMessage = SALE_COMP_MSG;
				} else if (pobTran->srTRTRec.TransactionCode == REFUND) {
					inLoadTRTRec(pobTran, REFUND);
					vdSGCode(REFUND);
					pobTran->srTRTRec.Offline= VS_TRUE;
					pobTran->srBKey.fOffline= VS_TRUE;
					pobTran->srBRec.lnMessage = SALE_COMP_MSG;
				}
				pobTran->inEMVCardDecision = EMV_OFFLINE_AUTH;
	            //pobTran->srBKey.fOffline = VS_TRUE;
	            //pobTran->srTRTRec.Offline = VS_TRUE;
				//KiaSoon 070206: For CALL REFERRAL ADVICE, USE BACK THE ARQC DE55 DATA To avoid AAC ADVICE UPLOADED
				//inResult= inRunFunction(pobTran, EMV_ADD_DATA_TO_BATCH);
           		//if( inResult != VS_SUCCESS)
				//	return(VS_ERR);
				LOG_PRINTFF((0x08L, "inRunFunction(pobTran, BUILD_AND_SEND_PACKET"));
				inResult = inRunFunction(pobTran, BUILD_AND_SEND_PACKET);  ////LIEM: NEED TO CHECK???
            	if( inResult != VS_SUCCESS) {
					return(VS_ERR);
				}
				LOG_PRINTFF((0x08L, "inRunFunction(pobTran, EEP_END_COMM"));
				inResult = inRunFunction(pobTran, EEP_END_COMM);
		        if( inResult != VS_SUCCESS) {
					return(VS_ERR);
				}
				inResult = inRunFunction(pobTran, UPDATE_BATCH);
	            if( inResult != VS_SUCCESS){
					return(VS_ERR);
				}
				inResult = inRunFunction(pobTran, UPDATE_ACCUM);
	            if( inResult != VS_SUCCESS) {
					return(VS_ERR);
				}
				inResult = inRunFunction(pobTran, UPDATE_TERM_INV_AND_HOST_INV);
	            if( inResult != VS_SUCCESS){
					return(VS_ERR);
				}
				//jrd
	            //strlcpy(pobTran->srBRec.szAuthCode, TC_GEN2AC_APPROVE, RESP_CODE_SIZE);
	            vdGetMessageFromFile( TRANS_APP_MSG, szMessage);
	            vdSGRespMsg(szMessage);
				inResult = inRunFunction(pobTran, CPAC_DISPLAY_RESPONSE);
	            if(inResult != VS_SUCCESS) {
        			return VS_ERR;
        		}
				inResult = inRunFunction(pobTran, CITI_REPRINT_FILE_COPY);
	            if( inResult != VS_SUCCESS) {
        			return VS_ERR;
        		}

				inResult = inRunFunction(pobTran, CITI_PRINT_RECEIPT);
       			if( inResult != VS_SUCCESS){
					return(VS_ERR);
				}
				inResult = inRunFunction(pobTran, EMV_SPLIT_SALES);
       			if( inResult != VS_SUCCESS){
					return(VS_ERR);
				}
				inResult = inRunFunction(pobTran, EMV_REMOVE_CARD);
				if( inResult != VS_SUCCESS){
					return(VS_ERR);
				}
		        pobTran->srBRec.inTransactionResult = AUTHORIZED;
				inPFRStateStoreAll(PFR_BEGIN_EMV_UPDATE_BATCH ,pobTran,1,1);
				return(BRANCH_EXIT);
			}
			/* end this handles the bank referral of EMV*/
			usEMVGetTLVFromColxn(0x9f27, &btCID, &tagLen); 
			memset(buff, 0x00, sizeof(buff));
			LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[??? = 0x%X]", 0x9f27, btCID));	

			switch(btCID & 0xC0) {
				case 0: //Declined --- AAC
					pobTran->srBRec.inTransactionResult = DECLINED;
					strlcpy(pobTran->srBRec.szAuthCode, AAC_GEN2AC_DECLINE, RESP_CODE_SIZE);	 // KK added
					//vdSGErrorMessage(EMV_DECLINE_MSG21);
					//LeeChyi - 29122050: Added in for response 51
					//KiaSOon - 10022006: Amend to read the response message from resp file. 
					if (!(strcmp((char*)srISO.pszField39, "00") == 0) && !(strcmp((char*)srISO.pszField39, "11") == 0) && !(strcmp((char*)srISO.pszField39, "10") == 0)) {
						vdCPACDispRespMsg(pobTran);
					} else {
						vdSGErrorMessage(EMV_BAD_DATA_FORMAT_MSG21);
						vdSGRespMsg("");
					}
					if ((strcmp((char*)srISO.pszField39, "01") == 0)||(strcmp((char*)srISO.pszField39, "02") == 0)) {
						vdSGErrorMessage(0L);
					}
					//TO DO REVERSAL HANDLING HERE only if transaction went online
					szGetESTRID(szRID);
					if(((inHostDecision == HOST_AUTHORISED) ||//(strcmp((char*)srISO.pszField39, "01") == 0) ||
						((inIsDigits(pobTran->srBRec.szRespCode) == VS_FALSE) &&
						((strncmp(szRID, "A000000004", 10) == 0) || (strncmp(szRID, "A000000010", 10) == 0)))) &&
						((pobTran->srTRTRec.TransactionCode == SALE) ||
						(pobTran->srTRTRec.TransactionCode == REFUND) ||
						//KiaSoon 270206: add in for card verification reversal
						// (pobTran->srTRTRec.TransactionCode == AUTH_ONLY) || // disable it
						// (pobTran->srTRTRec.TransactionCode == PRE_AUTH) ||  // disable it
						(pobTran->srTRTRec.TransactionCode == CASH_ADV))) {
						inUpdateReversalTVR(); //edi
						inResult = inRunFunction(pobTran, RENAME_REVERSAL_FILE);
						//jrd spqalog075 spqalog076
						LOG_PRINTFF((0x08L, "Calling inCPACDoReversal...1"));
						//inCPACDoReversal(pobTran, CPAC_SEND_SIZE);
						//inImamReversalSendReceive(pobTran, CPAC_SEND_SIZE);
						LOG_PRINTFF((0x08L, "Calling inCPACDoReversal...Ended"));
					}
					//spqalog074
					inResult = inRunFunction(pobTran, CITI_END_MODEM);
			        if( inResult != VS_SUCCESS) {
						return(VS_ERR);
					}
					//spqalog074
					return VS_ERR;
				case 0x40: //Offline Approval --- TC
					/*KiaSoon Started 06022006: To store 2nd GEN AC DATA*/
					inOffset = inMakeEMVBatchData(TAG_9500_TVR, (unsigned char*) bTagOutput);
					inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_95_TVR_LEN_2ND, (unsigned char*)&inOffset, sizeof(int));
					inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_95_TVR_2ND,  bTagOutput, inOffset);
					inOffset = inMakeEMVBatchData(TAG_9F26_APPL_CRYPTOGRAM, (unsigned char*) bTagOutput);
					inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F26_APP_CRYPTOGRAM_LEN_2ND, (unsigned char*)&inOffset, sizeof(int));
					inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F26_APP_CRYPTOGRAM_2ND,  bTagOutput, inOffset);
					inOffset=0;
					/*KiaSoon Ended */
					#if 0
					if(((inHostDecision == FAILED_TO_CONNECT) ||(pobTran->fReferral == VS_TRUE)) &&
						((pobTran->srTRTRec.TransactionCode == SALE) || (pobTran->srTRTRec.TransactionCode == REFUND))) {
						//Store this transaction as an offline sale/refund transaction and trickle feed it to the host
						if(pobTran->srTRTRec.TransactionCode == SALE) {
		            		inLoadTRTRec(pobTran, SALE_OFFLINE);
							vdSGCode(SALE_OFFLINE);
		            		pobTran->srTRTRec.TransactionCode = SALE_OFFLINE;
							pobTran->srBRec.lnMessage = SALE_OFFLINE_MSG;
		            		//pobTran->srBRec.lnMessage = SALE_COMP_MSG;
						} else if(pobTran->srTRTRec.TransactionCode == REFUND) {
							inLoadTRTRec(pobTran, REFUND);
							vdSGCode(REFUND);
							//pobTran->srBRec.lnMessage = SALE_COMP_MSG;
						}
						pobTran->inEMVCardDecision = EMV_OFFLINE_AUTH;
		            	//pobTran->srBKey.fOffline = VS_TRUE;
		            	//pobTran->srTRTRec.Offline = VS_TRUE;
						inResult= inRunFunction(pobTran, EMV_ADD_DATA_TO_BATCH);
			            if( inResult != VS_SUCCESS) {
							return(VS_ERR);
						}
						inResult = inRunFunction(pobTran, BUILD_AND_SEND_PACKET);  //LIEM: NOT USED
			            if( inResult != VS_SUCCESS) {
							return(VS_ERR);
						}
						inResult = inRunFunction(pobTran, EEP_END_COMM);
			            if( inResult != VS_SUCCESS) {
							return(VS_ERR);
						}
						inResult = inRunFunction(pobTran, UPDATE_BATCH);
		            	if( inResult != VS_SUCCESS) {
							return(VS_ERR);
						}
						inResult = inRunFunction(pobTran, UPDATE_ACCUM);
		            	if( inResult != VS_SUCCESS){
							return(VS_ERR);
						}
						inResult = inRunFunction(pobTran, UPDATE_TERM_INV_AND_HOST_INV);
		            	if( inResult != VS_SUCCESS) {
							return(VS_ERR);
						}
						//jrd
		            	//strlcpy(pobTran->srBRec.szAuthCode, TC_GEN2AC_APPROVE, RESP_CODE_SIZE);
            			vdGetMessageFromFile( TRANS_APP_MSG, szMessage);
            			vdSGRespMsg(szMessage);
						inResult = inRunFunction(pobTran, CPAC_DISPLAY_RESPONSE);
		            	if(inResult != VS_SUCCESS) {
            				return VS_ERR;
            			}
						inResult = inRunFunction(pobTran, CITI_REPRINT_FILE_COPY);
		            	if( inResult != VS_SUCCESS) {
            				return VS_ERR;
            			}
						inResult = inRunFunction(pobTran, CITI_PRINT_RECEIPT);
		            	if( inResult != VS_SUCCESS){
							return(VS_ERR);
						}
						inResult = inRunFunction(pobTran, EMV_SPLIT_SALES);
		            	if( inResult != VS_SUCCESS) {
							return(VS_ERR);
						}
						inResult = inRunFunction(pobTran, EMV_REMOVE_CARD);
		            	if( inResult != VS_SUCCESS) {
							return(VS_ERR);
						}
			            pobTran->srBRec.inTransactionResult = AUTHORIZED;
						inPFRStateStoreAll(PFR_BEGIN_EMV_UPDATE_BATCH ,pobTran,1,1);
						return(BRANCH_EXIT);
					} else
					#endif
					if(((pobTran->srTRTRec.TransactionCode == AUTH_ONLY)  ||
						(pobTran->srTRTRec.TransactionCode == PRE_AUTH) ||
						(pobTran->srTRTRec.TransactionCode == IMAM_CARDVER) ||
						(pobTran->srTRTRec.TransactionCode == CASH_ADV)) && (pobTran->fReferral == VS_TRUE)) {
						if((pobTran->srTRTRec.TransactionCode == PRE_AUTH) ||
							(pobTran->srTRTRec.TransactionCode == CASH_ADV)) { //Need to store in the open tab batch
							inResult = inRunFunction(pobTran, CPAC_UPDATE_BATCH);
							if( inResult != VS_SUCCESS) {
								return(VS_ERR);
							}
							inResult = inRunFunction(pobTran, UPDATE_BATCH);
							if( inResult != VS_SUCCESS) {
								return(VS_ERR);
							}
							inResult = inRunFunction(pobTran, UPDATE_ACCUM);
			            	if( inResult != VS_SUCCESS) {
								return(VS_ERR);
							}
							inResult = inRunFunction(pobTran, UPDATE_TERM_INV_AND_HOST_INV);
			            	if( inResult != VS_SUCCESS){
								return(VS_ERR);
							}
						}
						inResult = inRunFunction(pobTran, UPDATE_TERM_INV_AND_HOST_INV);
						if( inResult != VS_SUCCESS) {
							return(VS_ERR);
						}
		            	strlcpy(pobTran->srBRec.szAuthCode, TC_GEN2AC_APPROVE, RESP_CODE_SIZE);
            			vdGetMessageFromFile( TRANS_APP_MSG, szMessage);
            			vdSGRespMsg(szMessage);
						inResult = inRunFunction(pobTran, CPAC_DISPLAY_RESPONSE);
            			if( inResult != VS_SUCCESS) {
            				return VS_ERR;
            			}
						inResult = inRunFunction(pobTran, CITI_REPRINT_FILE_COPY);
						if( inResult != VS_SUCCESS) {
            				return VS_ERR;
            			}
						inResult = inRunFunction(pobTran, CITI_PRINT_RECEIPT);
		            	if( inResult != VS_SUCCESS){
							return(VS_ERR);
						}
						inResult = inRunFunction(pobTran, EMV_SPLIT_SALES);
		            	if( inResult != VS_SUCCESS){
							return(VS_ERR);
						}
						inResult = inRunFunction(pobTran, EMV_REMOVE_CARD);
						if( inResult != VS_SUCCESS) {
							return(VS_ERR);
						}
						pobTran->srBRec.inTransactionResult = AUTHORIZED;
						inPFRStateStoreAll(PFR_BEGIN_EMV_UPDATE_BATCH ,pobTran,1,1);
						return(BRANCH_EXIT);
					}
//					else if ( (inHostDecision==HOST_AUTHORISED) && (pobTran->srTRTRec.TransactionCode==SALE) )  //jrd spqa correction for tc upload of CITI_EPP_SALE
					/* Thiru 19012005, added to send TC_UPLOAD after EPP SALE */
					else if ( (inHostDecision==HOST_AUTHORISED) && 
						      (pobTran->srTRTRec.TransactionCode==SALE || pobTran->srTRTRec.TransactionCode == CITI_EPP_SALE || pobTran->srTRTRec.TransactionCode==PRE_AUTH || pobTran->srTRTRec.TransactionCode==AUTH_ONLY || pobTran->srTRTRec.TransactionCode==IMAM_CARDVER)) {
						/******************************************************/
						/* PATCH HERE ADD EMV DATA AGAIN BEFORE UPDATE_BATCH */
#if 0 //LIEM : Lousy Implementation == Disabled
						inResult= inRunFunction(pobTran, EMV_ADD_DATA_TO_BATCH); // YL 20060322 fr Siang Thye Kia Soon email
						if( inResult != VS_SUCCESS)	{							// YL 20060322 fr Siang Thye Kia Soon email
							return(VS_ERR);										// YL 20060322 fr Siang Thye Kia Soon email						
						}
						inResult = inRunFunction(pobTran, CPAC_DISPLAY_RESPONSE);
						if( inResult != VS_SUCCESS) {
							return(VS_ERR);
						}
						//jrd SPQALOG004
						inResult = inRunFunction(pobTran, CPAC_UPDATE_BATCH);
				        if( inResult != VS_SUCCESS){
							return(VS_ERR);
						}
						inResult = inRunFunction(pobTran, UPDATE_BATCH);
				        if( inResult != VS_SUCCESS){
							return(VS_ERR);
						}
						inResult = inRunFunction(pobTran, UPDATE_ACCUM);
				        if( inResult != VS_SUCCESS) {
							return(VS_ERR);
						}
						inResult = inRunFunction(pobTran, UPDATE_TERM_INV_AND_HOST_INV);   //jrd spqalog041
				        if( inResult != VS_SUCCESS) {
							return(VS_ERR);
						}
						inResult = inRunFunction(pobTran, CPAC_TOT_AMT_UPDATE);
				        if( inResult != VS_SUCCESS) {
							return(VS_ERR);
						}
						inResult = inRunFunction(pobTran, CITI_REPRINT_FILE_COPY);
			            if( inResult != VS_SUCCESS) {
	            			return VS_ERR;
	            		}
						LOG_PRINTFF((0x08L, "inRunFunction(pobTran, CITI_PRINT_RECEIPT)"));
						inResult = inRunFunction(pobTran, CITI_PRINT_RECEIPT);
			            if( inResult != VS_SUCCESS) {
							return(VS_ERR);
						}
						memcpy((char *)&pobTmpTran, (char *)pobTran,sizeof(TRANSACTION_OBJECT));
		            	//inLoadTRTRec(pobTran, SALE_OFFLINE);
						//vdSGCode(SALE_OFFLINE);
		            	//pobTran->srTRTRec.TransactionCode = SALE_OFFLINE;
		            	//pobTran->srBRec.lnMessage = SALE_OFFLINE_MSG;
						//pobTran->inEMVCardDecision = EMV_OFFLINE_AUTH;
						/* Thiru 19012005, added to send TC_UPLOAD after EPP SALE, the following settings are required only if it si SALE */
						if(inGGCode() == SALE) {
							pobTran->srBRec.lnMessage = SALE_OFFLINE_MSG;
							pobTran->inEMVCardDecision = EMV_OFFLINE_AUTH;
						}
						inLoadTRTRec(pobTran, TC_UPLOAD);
						vdSGCode(TC_UPLOAD);
		            	pobTran->srTRTRec.TransactionCode = TC_UPLOAD;
                        pobTran->srBRec.lnMessage = SALE_OFFLINE_MSG;  // YL 20060322 fr Siang Thye Kia Soon email
                        pobTran->inEMVCardDecision = EMV_OFFLINE_AUTH;  // YL 20060322 fr Siang Thye Kia Soon email		            			
						//inResult = inRunFunction(pobTran, CITI_END_MODEM); // LIEM ADD: MUST BE END FIRST
						LOG_PRINTFF((0x08L, "inRunFunction(pobTran, BUILD_AND_SEND_PACKET) in case 0x40==> TC Upload"));
						inResult = inRunFunction(pobTran, BUILD_AND_SEND_PACKET);	//LIEM: NOT USED					
			            if( inResult != VS_SUCCESS) {
							//spqalog017
							inEMVStoreTCTrans(pobTran);
							inRunFunction(pobTran, CITI_END_MODEM);
							return(VS_ERR);
						}
						inResult = inRunFunction(pobTran, CITI_END_MODEM);
			            if( inResult != VS_SUCCESS) {
							LOG_PRINTF(("END MoDEM ERROR*********"));
							return(VS_ERR);
						}
						memcpy((char *)pobTran, (char *)&pobTmpTran,sizeof(TRANSACTION_OBJECT));
						if (pobTran->srTRTRec.TransactionCode==SALE ) {
							LOG_PRINTF(("SALE*********"));
			            	inLoadTRTRec(pobTran, SALE);
			            }
			            if (pobTran->srTRTRec.TransactionCode==CITI_EPP_SALE ) {
			            	LOG_PRINTF(("CITI_EPP_SALE*********"));
			            	inLoadTRTRec(pobTran, CITI_EPP_SALE);
			            }
						/*
						inResult = inRunFunction(pobTran, CITI_REPRINT_FILE_COPY);
		            	if( inResult != VS_SUCCESS) {
            				return VS_ERR;
            			}
						inResult = inRunFunction(pobTran, CITI_PRINT_RECEIPT);
		            	if( inResult != VS_SUCCESS) {
							return(VS_ERR);
						}
						*/
						inResult = inRunFunction(pobTran, EMV_SPLIT_SALES);
		            	if( inResult != VS_SUCCESS) {
							return(VS_ERR);
						}
						inResult = inRunFunction(pobTran, EMV_REMOVE_CARD);
		            	if( inResult != VS_SUCCESS){
							return(VS_ERR);
						}
			            pobTran->srBRec.inTransactionResult = AUTHORIZED;
						inPFRStateStoreAll(PFR_BEGIN_EMV_UPDATE_BATCH ,pobTran,1,1);
						return(BRANCH_EXIT);
#else
						return (VS_SUCCESS);
#endif			
					} else {
						pobTran->srBRec.inTransactionResult = AUTHORIZED;
					}
					break;
				default:
					vdEMVDisplayErrorMsg((btCID & 0xC0));
					//inEMVAPIRemoveCard(pobTran);
					pobTran->srBRec.inTransactionResult = CANCELLED;
					vdSGErrorMessage(TRANS_FAIL_ERR_MSG21);
					return(VS_ERR);
			}

		} else{
			//Create reversal if card is removed or chip error is returned
			if((inResult == CHIP_ERROR) || (inResult == CARD_REMOVED) ||(inResult == BAD_DATA_FORMAT)||(inResult == 39321)&&
				(pobTran->srTRTRec.Offline == VS_FALSE)) {
					if (pobTran->srTRTRec.TransactionCode != AUTH_ONLY && pobTran->srTRTRec.TransactionCode != IMAM_CARDVER) { //
						inUpdateReversalTVR(); //edi
						inRunFunction(pobTran, RENAME_REVERSAL_FILE);
						//jrd spqalog089
						//inCPACDoReversal(pobTran, CPAC_SEND_SIZE);  //LIEM
						LOG_PRINTFF((0x08L, "Calling inCPACDoReversal...2"));
						//inImamReversalSendReceive(pobTran, CPAC_SEND_SIZE);
					}
			}
			vdPromptManager((unsigned short)inResult);
			//To supress any other error msg
    		vdSGErrorMessage(0L);
    		vdSGRespMsg("");
			//inEMVAPIRemoveCard(pobTran);
			inRunFunction(pobTran, CITI_END_MODEM);  // spqalog033 spqalog017
			return (VS_ERR);
		}
		inPFRStateStoreAll(PFR_BEGIN_EMV_UPDATE_BATCH ,pobTran,1,1);
	}
	LOG_PRINTFF((0x08L, "EMV_USE_HOST_DATA = inEMVAPIUseHostDataFlow ==================== OK"));
    return(VS_SUCCESS);
}


int inEMVAPIDataAuthentication(TRANSACTION_OBJECT *pobTran)
{
	int inResult;

	LOG_PRINTFF((0x08L, "EMV_DATA_AUTH = inEMVAPIDataAuthentication ====================="));
	if(pobTran->inChipStatus == EMV_CARD){
		LOG_PRINTFF((0x08L, "API: inVXEMVAPDataAuthentication ============"));
		inResult = inVXEMVAPDataAuthentication(NULL);
		LOG_PRINTFF((0x08L, "API: inVXEMVAPDataAuthentication ============ RetVal=[%d]", inResult));
		if (inResult != SUCCESS){
			vdPromptManager((unsigned short)inResult);
			//inEMVAPIRemoveCard(pobTran);

			if (inResult == CHIP_ERROR) {	// Set chip failure flag (chip failure is possible for DDA)
				vdEMVSetICCReadFailure(VS_TRUE);
				//vdDisplayFallbackMsg(pobTran);
				if (inGetFallbackAllowedFlag()) {
			    	vdSGErrorMessage(EMV_USE_MAG_STRIPE);
					//To set timer for the chip card to be swiped
					vdEMVSetFallbackTime();
				} else {
			    	vdSGErrorMessage(EMV_FAILURE_MSG21);
				}
			}
			return(VS_ERR);
		}
	}
	//Accepting amount after data authentcation if amount is not part of PDOL.
	//If this has to be done before data auth, then application needs to handle this accordingly.
/*
	if ((inResult = usEMVGetTLVFromColxn(TAG_9F02_AMT_AUTH_NUM, (byte*)&ulAmt, &tagLen)) != EMV_SUCCESS)
	{
		inResult = usAmtEntryFunc(&ulAmt);

		pobTran->srBRec.lnBaseTransactionAmount = lnGlobalAmount;

		if(inResult != EMV_SUCCESS)
			return(inResult);

		usEMVAddAmtToCollxn(ulAmt);
	}*/
	LOG_PRINTFF((0x08L, "EMV_DATA_AUTH = inEMVAPIDataAuthentication ===================== OK"));
   	return(VS_SUCCESS);
}

int inEMVUpdateSplitSales(TRANSACTION_OBJECT *pobTran)
{
	if(pobTran->srBRec.inChipStatus == EMV_CARD)
	{
		if ((pobTran->srBRec.inTransactionResult == AUTHORIZED) )
			bUpdateLogforSplitSales();
	}

	return (VS_SUCCESS);
}

int inEMVAPISetOffline (TRANSACTION_OBJECT *pobTran)
{
   //LOG_PRINTFF((0x08L, "inEMVAPISetOffline"));

	if (pobTran->inChipStatus == EMV_CARD)
        // Chip card will decide if transaction should be online, so set TRT to offline
        vdSetOffline(pobTran, VS_TRUE);
    return(VS_SUCCESS);
}

int inEMVAPIGetBaseAmount(TRANSACTION_OBJECT *pobTran)
{
	int inRet = VS_SUCCESS;
	unsigned short result;
	unsigned short tagLen;
	unsigned long ulAmt = 0L;

	if (pobTran->inChipStatus == EMV_CARD)
	{
		if ((result = usEMVGetTLVFromColxn(TAG_9F02_AMT_AUTH_NUM, (byte *)&ulAmt, &tagLen)) != EMV_SUCCESS)
		{

			result = usAmtEntryFunc(&ulAmt);


			if(result != EMV_SUCCESS)
				return(result);

			usEMVAddAmtToCollxn(ulAmt);
		}

		pobTran->srBRec.lnBaseTransactionAmount = lnGlobalAmount;
	}
	else
		inRet = inRunFunction(pobTran, CUST_GET_BASE_AMOUNT);

    return (inRet);
}


/**********************************/
/* EMV Tags/Debug report printing */
/**********************************/
int inEMVLogReportOperation(TRANSACTION_OBJECT *pobTran)
{
	int		inFHandle, inResult, i;
	int		inToday;
	char	szReadBuff1[4+1];
	char	szReadBuff2[30+1];

    char szTemplateFileName[FILENAME_SIZE+1];
	char szTag[10+1];
	char szTAGName[30+1];
	char szTmp[1+1];

	vdSetReportDateAndTime();
	inToday = gsrStats.chDay-0x30;

	strcpy(szTemplateFileName, STATIC_DATA_PATH);
       strcat(szTemplateFileName,STATS_FRM);

	if (inGetPrinterType() == NOPRINTER  && fGetEnablePrinter())
    {
        vdDisplayMessageFromFile( NO_PRINTER_MSG, WARNING_MSG);
        return(VS_SUCCESS);
    }

    if (!fGetEnablePrinter())
        return(VS_SUCCESS);

    vdDisplayMessageFromFile( PRINTING_MSG, STATUS_MSG );

    if (inSwitchTemplate(szTemplateFileName) < 0)
    {
        vdDisplayMessageFromFile( FORMATER_ERR_MSG, ERROR_MSG);

        return(VS_ERR);
    }

	/* -- take charge -- */
	p350ColumnMode ( COLUMN_TYPE_42 );

	/* -- print the header lines here -- */
	if (inPrintLines( &obPrinter, 1, 4, 1, (fGetDemoMode() ? 1L : 0L) ) != VS_SUCCESS)
	{

		return( VS_ERR );
	}

	#if 0
	memset(gsrEMVLogRpt.szEMVData, 0x00, sizeof(gsrEMVLogRpt.szEMVData));
	hex_2_asc((byte *)gsrEMVLogRpt.szEMVData, pszGlobalIssuerScriptResults, 20);	// Convert to NULL-terminated string
	inPrintLines(&obPrinter,30,30, NO_BL_LINE, 0L);
	#endif /* 0 */
	{
		char buff[128];
		char pBuff[128];

		p350ColumnMode(COLUMN_TYPE_42);

		memset(buff, 0x00, sizeof(0x00)); 
		strcpy(buff, szGetEMVTACDenial());
		sprintf(pBuff, "TAC DENIAL = [%s]\n", buff);
		shSpool(&obPrinter, pBuff);

		memset(buff, 0x00, sizeof(0x00)); 
		strcpy(buff, szGetEMVTACOnline());
		sprintf(pBuff, "TAC ONLINE = [%s]\n", buff);
		shSpool(&obPrinter, pBuff);

		memset(buff, 0x00, sizeof(0x00)); 
		strcpy(buff, szGetEMVTACDefault());
		sprintf(pBuff, "TAC DEFAULT = [%s]\n", buff);
		shSpool(&obPrinter, pBuff);
	}
	
	inFHandle = open( "emvtags.txt", O_RDONLY);

	if( inFHandle < 0 )
	{
		vdDisplayWarningString ("EMVTAGS.TXT file not found");
		vdDelay(2000);

		return( VS_ERR );
	}
#if 0
	if (pobTran->inChipStatus == NOT_USING_CHIP)
	{
		vdDisplayWarningString ("No EMV Data Available to Print");
		vdDelay(2000);
		return( VS_ERR );
	}
#endif /* 0 */
	do
	{
		memset(szReadBuff1, 0x00, sizeof (szReadBuff1));
		memset(szReadBuff2, 0x00, sizeof (szReadBuff2));

		i=0;
		do
		{
			memset(szTmp, 0x00, sizeof (szTmp));

			inResult = read(inFHandle, (char *)szTmp, 1);
			szReadBuff1[i]=szTmp[0];
			i++;
		}while ((inResult > 0 ) && (szTmp[0] !='\t'));

		if (inResult <=0)
		{
			close( inFHandle );

			 break;
			//return( VS_ERR );
		}
		else
		{
			szReadBuff1[i-1] = 0x00;
		}

		i=0;
		do
		{
			memset(szTmp, 0x00, sizeof (szTmp));

			inResult = read(inFHandle, (char *)szTmp, 1);
			szReadBuff2[i]=szTmp[0];
			i++;
		}while ((inResult > 0) && (szTmp[0] !='\n'));

		if (inResult <=0)
		{
			close( inFHandle );

			return( VS_ERR );
		}
		else
		{
			szReadBuff2[i-1] = 0x00;
		}

		//Print the EMV Log TVL Data
		memset(szTag,0x00,sizeof(szTag));
		memset(szTAGName,0x00,sizeof(szTAGName));

		strcpy(szTag,szReadBuff1);
		strcpy(szTAGName,szReadBuff2);
		if( inPrintEMVLogData((char*) szTag, (char*)szTAGName, (strlen(szTag)/2) ) != VS_SUCCESS )
		{
			close( inFHandle );

			return( VS_ERR );
		}

	}while ((inResult > 0) && (szTmp[0] != 0x00));

	close( inFHandle );

	if (inPrintLines(&obPrinter,27,32, NO_BL_LINE, 0L) != VS_SUCCESS)
	{

		return (VS_ERR);
	}


	vdFormFeed( &obPrinter );
	p350ColumnMode ( inGetP350ColMode() );



	return( VS_SUCCESS );

}

int inPrintEMVLogData(char* szTAG, char* szName, int inTAGLen )
{
	unsigned short usLen;
	unsigned short usResult;
	unsigned short usTag;
	char stConver[10+1];
	byte btTmp[250+1];
	char szPrintBuff[250+1];  //Without space
	char szPrintBuff2[500+1]; //With space
	char *pszPrintBuff2;
	int i,j, inRemain;
	char buff[256];

	//Reset the variable
	memset((char*)stConver,0x00,sizeof(stConver));
	memset((char*)szPrintBuff, 0x00, sizeof(szPrintBuff));
	memset((char*)szPrintBuff2, 0x20, sizeof(szPrintBuff2));
	memset((char*)btTmp, 0x00, sizeof(btTmp));
	memset((char*)gsrEMVLogRpt.szTAGName, 0x00, sizeof(gsrEMVLogRpt.szTAGName));
	memset((char*)gsrEMVLogRpt.szTAG, 0x00, sizeof(gsrEMVLogRpt.szTAG));
	memset((char*)gsrEMVLogRpt.szLength, 0x00, sizeof(gsrEMVLogRpt.szLength));
	memset((char*)gsrEMVLogRpt.szEMVData, 0x00, sizeof(gsrEMVLogRpt.szEMVData));

	//Make the EMV TAG Name
	strcpy((char*)gsrEMVLogRpt.szTAGName, szName);

	//Make the EMV TAG Data
	//usTag = atoi(szTAG);
	SVC_DSP_2_HEX((char*)szTAG, (char *)stConver, inTAGLen);

	usTag = (unsigned short)stConver[0];
	usTag = usTag << 8;
	usTag |= (unsigned short)stConver[1];

	usResult = usEMVGetTLVFromColxn((unsigned short)usTag, (byte *)btTmp, (unsigned short *) &usLen);
	memset(buff, 0x00, sizeof(buff));
	if (usLen<128) hex_2_asc((BYTE *)buff, btTmp, usLen);
	LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[??? = %s]  -- in inPrintEMVLogData", usTag, buff));	

	if (usResult == EMV_SUCCESS && usLen)	// If Cardholder Name exists
	{
		strcpy((char*)gsrEMVLogRpt.szTAG,szTAG);
	 	sprintf(gsrEMVLogRpt.szLength,"%02X",(int)usLen);
		hex_2_asc((BYTE *)szPrintBuff, btTmp, usLen);
		j=0;
		for (i=0; i< (usLen*2); i+=2)
		{
			szPrintBuff2[j]=szPrintBuff[i];
			szPrintBuff2[j+1]=szPrintBuff[i+1];
			j += 3;
		}
		szPrintBuff2[j]=0x00;
	}
	else
	{
		strcpy((char*)gsrEMVLogRpt.szTAG,szTAG);
		strcpy(gsrEMVLogRpt.szLength,"00");
		strcpy(szPrintBuff2,"No Data");
		szPrintBuff2[7]=0x00;
	}

	//Print TAG Name
	if (inPrintLines(&obPrinter,EMV_TAG_NAME_START,EMV_TAG_NAME_END, NO_BL_LINE, 0L) != VS_SUCCESS)
	{
		return (VS_ERR);
	}

	pszPrintBuff2 = szPrintBuff2;
	inRemain = strlen(pszPrintBuff2);
	while (inRemain > 42)
	{
		memset((char*)gsrEMVLogRpt.szEMVData, 0x00, sizeof(gsrEMVLogRpt.szEMVData));
		strncpy(gsrEMVLogRpt.szEMVData,pszPrintBuff2, 42);
		//Print TAG Data
		if (inPrintLines(&obPrinter,EMV_DATA_START,EMV_DATA_END, NO_BL_LINE, 0L) != VS_SUCCESS)
		{
			return (VS_ERR);
		}

		pszPrintBuff2 = pszPrintBuff2 + 42;
		inRemain = strlen(pszPrintBuff2);
	}

	memset((char*)gsrEMVLogRpt.szEMVData, 0x00, sizeof(gsrEMVLogRpt.szEMVData));
	strcpy(gsrEMVLogRpt.szEMVData,pszPrintBuff2);

	if (inPrintLines(&obPrinter,EMV_DATA_START,EMV_DATA_END, NO_BL_LINE, 0L) != VS_SUCCESS)
	{
		return (VS_ERR);
	}

	return( VS_SUCCESS );
}

/*

The following function is just to print some status info in the screen inorder to help debugg the SoftPay EMV module
First two strings are assumed to be null terminated ASCII strings and the third parameter a hex string.

*/

void vdEMVDebugPrint(char* pszStr1, unsigned char* pstValueStr, int inDataLen)
{

#if EMV_DEBUG_PRINT

FHANDLE hFHandle;
int inPos = 0;
char szTempBuf[RECEIPT_HEADER_SIZE + 1];
unsigned char ucDataBuf[50];

	if ((hFHandle = open("EMVDBG.TXT", O_RDWR)) < 0)
		return;

    	lseek(hFHandle, 0l, SEEK_END);

	memset(szTempBuf, 0, sizeof(szTempBuf));
	memset(ucDataBuf, 0, sizeof(ucDataBuf));

	strncpy(szTempBuf, pszStr1, RECEIPT_HEADER_SIZE); // To make sure there is a null at the end
	write(hFHandle, (char*) szTempBuf, RECEIPT_HEADER_SIZE);


	while(inDataLen > 0)
	{
		if (inDataLen <= 20)
		{
			hex_2_asc(ucDataBuf, pstValueStr+inPos, inDataLen);
			write(hFHandle, (char*) ucDataBuf, inDataLen * 2); // Coverted to ASCII, so double length
			break;
		}
		else
		{
			hex_2_asc(ucDataBuf, pstValueStr+inPos, 20);
			write(hFHandle, (char*) ucDataBuf, 40);
			inDataLen -=  20;
			inPos +=20;
		}
	}

	close(hFHandle);

#endif /* EMV_DEBUG_PRINT */

	return;

}


int inEMVDebugPrintReport(TRANSACTION_OBJECT *pobTran)
{
	return(VS_SUCCESS);
}

void vdFormatStringForPrint(unsigned char * ucSrcBuf, unsigned char * ucDestBuf,  int inSrcLen)
{
	int i, j =0;

	for (i=0; i< (inSrcLen*2); i+=2)
	{
		ucDestBuf[j]=ucSrcBuf[i];
		ucDestBuf[j+1]=ucSrcBuf[i+1];
		j += 3;
	}
	ucDestBuf[j]=0x00;
}

int inGetTerminalDecision(void)
{
	int inEMVForceOnline;

	if(inLoadTCTRec(0) != VS_SUCCESS)
	{
		vdDisplayMessageFromFile(TCT_ERR_MSG21, ERROR_MSG);
		return VS_ERR;
	}

	inEMVForceOnline = inGetEMVOnlineFlag();

	if(inEMVForceOnline == 1)
		return FORCED_ONLINE;
	else
		return 0;   //To check this return value with Toolkit

   }

int inImamGetTagIssuerData(unsigned char *szTag, int *inTagLen, unsigned char *szHexBuff, unsigned char *szValue)
{
	unsigned char szTagFound[10];
	unsigned char szTagFoundValue[256];
	int inTagFoundLen = 0;	
	int i = 0;
	int inRetval = -1;
	for (i=0; i<255 ;i++){
		memset(szTagFound, 0x00, sizeof(szTagFound));
		memset(szTagFoundValue, 0x00, sizeof(szTagFoundValue));
		if ((szHexBuff[i] & 0x0F) == 0x0F){
			memcpy(szTagFound, &szHexBuff[i], 2);
			inRetval = i;
			i = i+2;
			inTagFoundLen = szHexBuff[i];
			i = i+1;
			memcpy(szTagFoundValue, &szHexBuff[i], inTagFoundLen); 
			i = i+inTagFoundLen;
			i--;
		} else if (szHexBuff[i] != 0x00){
			memcpy(szTagFound, &szHexBuff[i], 1);
			inRetval = i;
			i = i+1;
			inTagFoundLen = szHexBuff[i];
			i = i+1;
			memcpy(szTagFoundValue, &szHexBuff[i], inTagFoundLen); 
			i = i+inTagFoundLen;
			i--;
		} else {
			return -1;
		}
		LOG_PRINT_HEX(szTagFound, 2);
		LOG_PRINT_HEX(szTagFoundValue, inTagFoundLen);
		if (!memcmp(szTagFound, szTag, *inTagLen)){
			memcpy(szValue, szTagFoundValue, inTagFoundLen); 
			*inTagLen = inTagFoundLen;
			return inRetval;
		}
	}	
	return -1;
}

int inEMVGetIssuerDataFromResponse(TRANSACTION_OBJECT *pobTran)
{
	int inRespField55Len;
	int inNumScripts = 0;
	int inPtLen = 2;

	if((pobTran->srBRec.inChipStatus == EMV_CARD) && (map_test(stMap8583, 55))) {
		char szTemp[4+1];
		memset(szTemp, 0x00, sizeof(szTemp));
		sprintf( szTemp , "%x%02x",(unsigned char)szEMVField55[0],(unsigned char)szEMVField55[1]);
		inRespField55Len = atoi(szTemp);
		//inRespField55Len = ((unsigned char)szEMVField55[0] * 10) + (unsigned char)szEMVField55[1];
		LOG_PRINTFF((0x08L, "F55 [%x%02x] = %d", (unsigned char)szEMVField55[0], (unsigned char)szEMVField55[1], inRespField55Len));
		if (inRespField55Len >= 254) inRespField55Len = 254;
		{
			unsigned char szHexBuff[256];
			unsigned char szTagValueFound[256];
			char szBuff[256];
			int inTagLen = 0;

			memset(szHexBuff, 0x00, sizeof(szHexBuff));
			memcpy(szHexBuff, &szEMVField55[2], inRespField55Len);

			inTagLen = 1; 
			memset(szTagValueFound, 0x00, sizeof(szTagValueFound));
			inPtLen = inImamGetTagIssuerData("\x91", &inTagLen, szHexBuff, szTagValueFound);
			inPtLen = inPtLen + 2;
			if (inPtLen >= 2){
				int inImamTag91Len = inTagLen+2;
				usEMVUpdateTLVInCollxn( TAG_91_ISS_AUTH_DATA , (byte *)szTagValueFound , inTagLen );
				memset(szBuff, 0x00, sizeof(szBuff));
				memcpy(szBuff, &szEMVField55[inPtLen] , inImamTag91Len);
				inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_91_LEN, (unsigned char*)&inImamTag91Len, sizeof(int));
				inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_91,  (unsigned char*)szBuff, inImamTag91Len);
			}

			inTagLen = 1;
			memset(szTagValueFound, 0x00, sizeof(szTagValueFound));
			inPtLen = inImamGetTagIssuerData("\x71", &inTagLen, szHexBuff, szTagValueFound);
			inPtLen = inPtLen + 2;
			if (inPtLen >= 2){
				// Process Issuer Script 71 
				inNumScripts = createScriptFiles((unsigned char*)&szEMVField55[inPtLen]);
				inGlobalNumberScripts  += inNumScripts;
			}

			inTagLen = 1;
			memset(szTagValueFound, 0x00, sizeof(szTagValueFound));
			inPtLen = inImamGetTagIssuerData("\x72", &inTagLen, szHexBuff, szTagValueFound);
			inPtLen = inPtLen + 2;
			if (inPtLen >= 2){
				// Need to process Issuer Script 72 
				inNumScripts = createScriptFiles((unsigned char*)&szEMVField55[inPtLen]);
				inGlobalNumberScripts += inNumScripts;
			}
		}
	}
	return VS_SUCCESS;
}

/*
int inEMVGetIssuerDataFromResponse(TRANSACTION_OBJECT *pobTran)
{

	char szBuffer[256+1], szTemp[4+1], szLen[4+1];
	int inRespField55Len,inTag91Len,inTag71Len,inTag72Len;
	int inNumScripts = 0;
	int   inPtLen = 2;
	char  chLength = 0;
	char buff[256+1];

	//map_set(stMap8583, 55);

	//memcpy((char*)szEMVField55, "00149110FB1DAAD92E7CED7530353030", 32);
	//SVC_DSP_2_HEX((char*)szEMVField55, (char*)szEMVField55,16);

	//memcpy((char*)szEMVField55, "01407144860F8C1600000A8E081122334455667788860F8C1E00000A8E089900AABBCCDDEEFF860F8C1600000A8E081122334455667788860F8C1E00000A8E089900AABBCCDDEEFF", 144);
	//memcpy((char*)szEMVField55, "01407244860F8C1600000A8E081122334455667788860F8C1800000A8E089900AABBCCDDEEFF860F8C1600000A8E081122334455667788860F8C1E00000A8E089900AABBCCDDEEFF", 144);
	//memcpy((char*)szEMVField55, "00727125860F841600000A8E087190E6ED0FEDCE41860F841600000A8E087190E6ED0FEDCE41", 74);
	//memcpy((char*)szEMVField55, "00727122900F841600000A8E087190E6ED0FEDCE41900F841600000A8E087190E6ED0FEDCE41", 74);
	//memcpy((char*)szEMVField55, "00727125860F841600000A8E087190E6ED0FEDCE41860F841600000A8E087190E6ED0FEDCE41", 74);
	//memcpy((char*)szEMVField55, "010471189F180400000001860F8C1600000A8E08112233445566778871189F180400000002860F8C1E00000A8E089900AABBCCDDEEFF", 108);
	//memcpy((char*)szEMVField55, "00727122860F8C1600000A8E081122334455667788860F8C1E00000A8E089900AABBCCDDEEFF", 76);
	//memcpy((char*)szEMVField55, "00687120860E0CDC04AC09031122334455667788860E0CDC04AC09089900AABBCCDDEEFF", 72);
	//memcpy((char*)szEMVField55, "00387111860F8C1600000A8E081122334455667788", 42);
	//memcpy((char*)szEMVField55, "0034710F8C1600000A8E081122334455667788", 38);
	//memcpy((char*)szEMVField55, "0256717E9F180400000001860F8C1E00000A8E081122334455667788860F8C1E00000A8E081122334455667788860F8C1E00000A8E081122334455667788860F8C1E00000A8E081122334455667788860F8C1E00000A8E081122334455667788860F8C1E00000A8E081122334455667788860F8C1E00000A8E081122334455667788", 260);
	//memcpy((char*)szEMVField55, "00767111900F841600000A8E08AA90E6ED0FEDCE417211860F8C1600000A8E087190E6ED0FEDCE41", 80);
	//memcpy((char*)szEMVField55, "00387111860D841600000A11223344556677889910", 42);
       //memcpy((char*)szEMVField55, "0034720F841600000A8E081122334455667788", 38);
	//memcpy((char*)szEMVField55, "0256717E9F180400000001860F8C1800000A8E081122334455667788860F8C1800000A8E08AABBCCDDEEFFAABB860F8C1800000A8E081122334455667788860F8C1800000A8E08AABBCCDDEEFFAABB860F8C1800000A8E081122334455667788860F8C1800000A8E08AABBCCDDEEFFAABB860F8C2400000A8E081122334455667788", 260);
	//memcpy((char*)szEMVField55, "00387111860F841E00000A11223344556677889910", 42);
	//memcpy((char*)szEMVField55, "00387111860F841600000A11223344556677889910", 42);
	//memcpy((char*)szEMVField55, "00387111860F842400000A01020304050607080910", 42);
	//memcpy((char*)szEMVField55, "010471189F180400000001860F8C1600000A8E08112233445566778871189F180400000002860F8C1E00000A8E089900AABBCCDDEEFF", 108);
	//memcpy((char*)szEMVField55, "00727122860F8C1600000A8E081122334455667788860F8C1E00000A8E089900AABBCCDDEEFF", 74);
	//memcpy((char*)szEMVField55, "00687120860E0CDC04AC09031122334455667788860E0CDC04AC09089900AABBCCDDEEFF", 72);
	//memcpy((char*)szEMVField55, "00387111860F8C1600000A8E081122334455667788", 42);
	//memcpy((char*)szEMVField55, "0034710F8C1600000A8E081122334455667788", 38);
	//memcpy((char*)szEMVField55, "01407144860F8C1800000A8E089900AABBCCDDEEFF860F8C2400000A8E081122334455667788860F8C2400000A8E081122334455667788860F8C1800000A8E089900AABBCCDDEEFF", 144);
	//memcpy((char*)szEMVField55, "0256717E9F180400000001860F8C1E00000A8E081122334455667788860F8C1E00000A8E081122334455667788860F8C1E00000A8E081122334455667788860F8C1E00000A8E081122334455667788860F8C1E00000A8E081122334455667788860F8C1E00000A8E081122334455667788860F8C1E00000A8E081122334455667788", 260);
	//memcpy((char*)szEMVField55, "00767111900F841600000A8E08AA90E6ED0FEDCE417111860F8C1600000A8E087190E6ED0FEDCE41", 80);
	//memcpy((char*)szEMVField55, "00387111860D841600000A11223344556677889910", 42);
	//memcpy((char*)szEMVField55, "0060711C861A8C24000215870901A1C39B90E31B335B8E084B8B380148FD6D0F", 64);
	//memcpy((char*)szEMVField55, "010872349F180400000001860F8C1E00000A8E089900AABBCCDDEEFF861A8C24000215870901A1C39B90E31B335B8E084B8B380148FD6D0F", 112);
	//SVC_DSP_2_HEX((char*)szEMVField55, (char*)szEMVField55, 37);


	if((pobTran->srBRec.inChipStatus == EMV_CARD) && (map_test(stMap8583, 55)))
	{
		memset(szTemp, 0x00, sizeof(szTemp));
		sprintf( szTemp , "%x%02x",(unsigned char)szEMVField55[0],(unsigned char)szEMVField55[1]);
		inRespField55Len = atoi(szTemp);
		//inRespField55Len = ((unsigned char)szEMVField55[0] * 10) + (unsigned char)szEMVField55[1];
		LOG_PRINTFF((0x08L, "F55 [%x%02x] = %d", (unsigned char)szEMVField55[0], (unsigned char)szEMVField55[1], inRespField55Len));
		if (inRespField55Len >= 254) inRespField55Len = 254;

		while (inPtLen < inRespField55Len)
		{
			switch ((unsigned char)szEMVField55[inPtLen])
			{
				case 0x91:

					// Get Issuer Authentication Data
					inPtLen++ ;
					//sprintf( szLen , "%02x",szEMVField55[inPtLen]);
					inTag91Len = (unsigned char) szEMVField55[inPtLen];//atoi(szLen);
					inPtLen++ ;
					if ((inTag91Len+inPtLen) > (inRespField55Len+2)){inPtLen--; break;} //
					memcpy( szBuffer, &szEMVField55[ inPtLen ] , inTag91Len);
					//inPrintWatchPacket((unsigned char*) &szEMVField55[inPtLen], inTag91Len,"joey91");
					usEMVUpdateTLVInCollxn( TAG_91_ISS_AUTH_DATA , (byte *)szBuffer , inTag91Len );
					{
						int inImamTag91Len = inTag91Len+2;
						char szImamBuff[128+1];
						memset(szImamBuff, 0x00, sizeof(szImamBuff));
						if (inPtLen>=2){
							memcpy(szImamBuff, &szEMVField55[inPtLen-2] , inImamTag91Len);
							inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_91_LEN, (unsigned char*)&inImamTag91Len, sizeof(int));
							inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_91,  (unsigned char*)szImamBuff, inImamTag91Len);
						}
					}
					memset(buff, 0x00, sizeof(buff));
					if (inTag91Len<128) hex_2_asc((BYTE *)buff, szBuffer, inTag91Len);
					LOG_PRINTFF((0x08L, "TAG(0x%X): EMVUpdateTLV[TAG_91_ISS_AUTH_DATA = %s]", TAG_91_ISS_AUTH_DATA, buff));

					inPtLen += inTag91Len;
					//usEMVUpdateTLVInCollxn( TAG_8A_AUTH_RESP_CODE , (byte *)&szEMVField55[inPtLen] , 2 );
					//inPtLen += inTag91Len ;
					break;

				case 0x71:

					// Get Issuer Script Tag 71
					inTag71Len =(unsigned char) szEMVField55[inPtLen+1];
					if ((inTag71Len+inPtLen) > (inRespField55Len)){inPtLen++; break;} //
					// Need to process Issuer Script 71 
					inNumScripts = createScriptFiles((unsigned char*)&szEMVField55[inPtLen]);
					// Need to process Issuer Script 1 OK 
					inPtLen += ( inTag71Len + 2 )  ;
					inGlobalNumberScripts  += inNumScripts;
					break;

				case 0x72:

					// Get Issuer Script Tag 72
					inTag72Len =(unsigned char) szEMVField55[inPtLen+1];
					if ((inTag72Len+inPtLen) > (inRespField55Len)){inPtLen++; break;} //
					// Need to process Issuer Script 72 
					inNumScripts = createScriptFiles((unsigned char*)&szEMVField55[inPtLen]);
					// Need to process Issuer Script 2 OK 
					inPtLen += ( inTag72Len + 2 )  ;
					inGlobalNumberScripts += inNumScripts;
					break;

				default:
					inPtLen++;



			}

		}

	}
	return VS_SUCCESS;
}
*/


int inEMVAddDataToBatch(TRANSACTION_OBJECT *pobTran)
{
	unsigned short usLen = 0;
	unsigned char bTagOutput[255];
	int inOffset = 0;
	unsigned char szTempBuff[6 + 1];
	char buff[256];

	///////Edi -AMEX EMV ///////////////////// 
	int amexFlag = 0;
	char szPanLo[20];
	char szPanHi[20];
	memset(szPanLo,0x00,sizeof(szPanLo));
	memset(szPanHi,0x00,sizeof(szPanHi));
	strncpy(szPanLo,szGetPANLo(),4);
	strncpy(szPanHi,szGetPANHi(),4);
	if(atoi(szPanLo) > 3400 && atoi(szPanHi) < 3499) amexFlag = 1;
	if(atoi(szPanLo) > 3700 && atoi(szPanHi) < 3799) amexFlag = 1;
	////////////////////////////	

	

	LOG_PRINTFF((0x08L, "EMV_ADD_DATA_TO_BATCH = inEMVAddDataToBatch ===================="));
if(pobTran->srBRec.inChipStatus == EMV_CARD && amexFlag == 0)
	{
		inOffset = inMakeEMVBatchData(TAG_8200_APPL_INTCHG_PROFILE, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_82_AIP_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_82_AIP, bTagOutput, inOffset);


		inOffset = inMakeEMVBatchData(TAG_9500_TVR, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_95_TVR_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_95_TVR,  bTagOutput, inOffset);



		inOffset = inMakeEMVBatchData(TAG_9A_TRAN_DATE, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9A_TXN_DATE_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9A_TXN_DATE,  bTagOutput, inOffset);


		inOffset = inMakeEMVBatchData(TAG_9C00_TRAN_TYPE, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9C_TXN_TYPE_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9C_TXN_TYPE,  bTagOutput, inOffset);


		inOffset = inMakeEMVBatchData(TAG_9F02_AMT_AUTH_NUM, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F02_AMT_AUTH_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F02_AMT_AUTH,  bTagOutput, inOffset);


		memset(szTempBuff, 0, sizeof(szTempBuff));
		usEMVUpdateTLVInCollxn(TAG_9F03_AMT_OTHER_NUM, szTempBuff, 6);
		memset(buff, 0x00, sizeof(buff));
		hex_2_asc((BYTE *)buff, szTempBuff, 6);
		LOG_PRINTFF((0x08L, "TAG(0x%X): EMVUpdateTLV[TAG_9F03_AMT_OTHER_NUM = %s]", TAG_9F03_AMT_OTHER_NUM, buff));	

		inOffset = inMakeEMVBatchData(TAG_9F03_AMT_OTHER_NUM, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F03_AMT_OTHR_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F03_AMT_OTHR,  bTagOutput, inOffset);


		inOffset = inMakeEMVBatchData(TAG_9F09_TERM_VER_NUM, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F09_APPLN_VER_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F09_APPLN_VER,  bTagOutput, inOffset);


		inOffset = inMakeEMVBatchData(TAG_9F10_ISSUER_APP_DATA, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F10_ISSUER_APP_DATA_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F10_ISSUER_APP_DATA,  bTagOutput, inOffset);


		inOffset = inMakeEMVBatchData(TAG_9F1A_TERM_COUNTY_CODE, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec,FID_EMV_TAG_9F1A_TERM_CRTY_CODE_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F1A_TERM_CRTY_CODE,  bTagOutput, inOffset);


		inOffset = inMakeEMVBatchData(TAG_9F1E_IFD_SER_NUM, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F1E_IFD_SER_NUM_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F1E_IFD_SER_NUM,  bTagOutput, inOffset);


		inOffset = inMakeEMVBatchData(TAG_9F26_APPL_CRYPTOGRAM, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F26_APP_CRYPTOGRAM_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F26_APP_CRYPTOGRAM,  bTagOutput, inOffset);



		inOffset = inMakeEMVBatchData(TAG_9F27_CRYPT_INFO_DATA, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F27_CID_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F27_CID,  bTagOutput, inOffset);


		inOffset = inMakeEMVBatchData(TAG_9F33_TERM_CAP, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F33_TERM_CAPABILITIES_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F33_TERM_CAPABILITIES,  bTagOutput, inOffset);


		inOffset = inMakeEMVBatchData(TAG_9F34_CVM_RESULTS, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F34_CVM_RESULTS_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F34_CVM_RESULTS,  bTagOutput, inOffset);


		inOffset = inMakeEMVBatchData(TAG_9F35_TERM_TYPE, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F35_TERM_TYPE_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F35_TERM_TYPE,  bTagOutput, inOffset);


		inOffset = inMakeEMVBatchData(TAG_9F36_ATC, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F36_ATC_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F36_ATC,  bTagOutput, inOffset);


		inOffset = inMakeEMVBatchData(TAG_9F37_UNPRED_NUM, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F37_UNPREDICT_NUMBER_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F37_UNPREDICT_NUMBER,  bTagOutput, inOffset);


		inOffset = inMakeEMVBatchData(TAG_9F41_TRANS_SEQ_COUNTER, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F41_TRANS_SEQ_COUNTER_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F41_TRANS_SEQ_COUNTER,  bTagOutput, inOffset);


		inOffset = inMakeEMVBatchData(TAG_9F53_TRAN_CURR_CODE, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F53_TRAN_CAT_CODE_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F53_TRAN_CAT_CODE,  bTagOutput, inOffset);

		//jrd
		inOffset = inMakeEMVBatchData(TAG_5F2A_TRANS_CURCY_CODE, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_5F2A_CURR_CODE_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_5F2A_CURR_CODE,  bTagOutput, inOffset);

		//edi
		inOffset = inMakeEMVBatchData(TAG_5F34_APPL_PAN_SEQNUM, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_5F34_PAN_SEQ_NUM_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_5F34_PAN_SEQ_NUM, bTagOutput, inOffset);


		inOffset = inMakeEMVBatchData(TAG_84_DF_NAME, (unsigned char*) bTagOutput);
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_84_DF_NAME_LEN, (unsigned char*)&inOffset, sizeof(int));
		inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_84_DF_NAME, bTagOutput, inOffset);

		}
		else if(pobTran->srBRec.inChipStatus == EMV_CARD && amexFlag == 1){
			inOffset = inMakeAmexEMVBatchData1(TAG_9F26_APPL_CRYPTOGRAM, (unsigned char*) bTagOutput);
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F26_APP_CRYPTOGRAM_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F26_APP_CRYPTOGRAM,  bTagOutput, inOffset);

			inOffset = inMakeAmexEMVBatchData2(TAG_9F10_ISSUER_APP_DATA, (unsigned char*) bTagOutput);
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F10_ISSUER_APP_DATA_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F10_ISSUER_APP_DATA,  bTagOutput, inOffset);

			inOffset = inMakeAmexEMVBatchData1(TAG_9F37_UNPRED_NUM, (unsigned char*) bTagOutput);
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F37_UNPREDICT_NUMBER_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F37_UNPREDICT_NUMBER,  bTagOutput, inOffset);

			inOffset = inMakeAmexEMVBatchData1(TAG_9F36_ATC, (unsigned char*) bTagOutput);
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F36_ATC_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F36_ATC,  bTagOutput, inOffset);

			inOffset = inMakeAmexEMVBatchData1(TAG_9500_TVR, (unsigned char*) bTagOutput);
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_95_TVR_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_95_TVR,  bTagOutput, inOffset);

			inOffset = inMakeAmexEMVBatchData1(TAG_9A_TRAN_DATE, (unsigned char*) bTagOutput);
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9A_TXN_DATE_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9A_TXN_DATE,  bTagOutput, inOffset);


			inOffset = inMakeAmexEMVBatchData1(TAG_9C00_TRAN_TYPE, (unsigned char*) bTagOutput);
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9C_TXN_TYPE_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9C_TXN_TYPE,  bTagOutput, inOffset);


			inOffset = inMakeAmexEMVBatchData1(TAG_9F02_AMT_AUTH_NUM, (unsigned char*) bTagOutput);
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F02_AMT_AUTH_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F02_AMT_AUTH,  bTagOutput, inOffset);

			//jrd
			inOffset = inMakeAmexEMVBatchData1(TAG_5F2A_TRANS_CURCY_CODE, (unsigned char*) bTagOutput);
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_5F2A_CURR_CODE_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_5F2A_CURR_CODE,  bTagOutput, inOffset);


			inOffset = inMakeAmexEMVBatchData1(TAG_9F1A_TERM_COUNTY_CODE, (unsigned char*) bTagOutput);
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec,FID_EMV_TAG_9F1A_TERM_CRTY_CODE_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F1A_TERM_CRTY_CODE,  bTagOutput, inOffset);

			inOffset = inMakeAmexEMVBatchData1(TAG_8200_APPL_INTCHG_PROFILE, (unsigned char*) bTagOutput);
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_82_AIP_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_82_AIP, bTagOutput, inOffset);


			memset(szTempBuff, 0, sizeof(szTempBuff));
			usEMVUpdateTLVInCollxn(TAG_9F03_AMT_OTHER_NUM, szTempBuff, 6);
			memset(buff, 0x00, sizeof(buff));
			hex_2_asc((BYTE *)buff, szTempBuff, 6);
			LOG_PRINTFF((0x08L, "TAG(0x%X): EMVUpdateTLV[TAG_9F03_AMT_OTHER_NUM = %s]", TAG_9F03_AMT_OTHER_NUM, buff));	
			
			inOffset = inMakeAmexEMVBatchData1(TAG_9F03_AMT_OTHER_NUM, (unsigned char*) bTagOutput);
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F03_AMT_OTHR_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F03_AMT_OTHR,  bTagOutput, inOffset);

			//edi
			inOffset = inMakeAmexEMVBatchData1(TAG_5F34_APPL_PAN_SEQNUM, (unsigned char*) bTagOutput);
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_5F34_PAN_SEQ_NUM_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_5F34_PAN_SEQ_NUM, bTagOutput, inOffset);


			inOffset = inMakeAmexEMVBatchData1(TAG_9F27_CRYPT_INFO_DATA, (unsigned char*) bTagOutput);
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F27_CID_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F27_CID,  bTagOutput, inOffset);


			//9F06 / 4F		
			inOffset = inMakeAmexEMVBatchData2(TAG_4F_AID, (unsigned char*) bTagOutput);
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_4F_AID_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_4F_AID,  bTagOutput, inOffset);
			
			inOffset = inMakeAmexEMVBatchData1(TAG_9F09_TERM_VER_NUM, (unsigned char*) bTagOutput);
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F09_APPLN_VER_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F09_APPLN_VER,  bTagOutput, inOffset);


			inOffset = inMakeAmexEMVBatchData1(TAG_9F34_CVM_RESULTS, (unsigned char*) bTagOutput);
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F34_CVM_RESULTS_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_TAG_9F34_CVM_RESULTS,  bTagOutput, inOffset);

			//9F0E 9F0F 9F0D
			inOffset = inMakeAmexEMVBatchData1(TAG_9F0E_IAC_DENIAL, (unsigned char*) bTagOutput);
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_IAC_DENIAL_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_IAC_DENIAL,  bTagOutput, inOffset);

			inOffset = inMakeAmexEMVBatchData1(TAG_9F0F_IAC_ONLINE, (unsigned char*) bTagOutput);
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_IAC_ONLINE_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_IAC_ONLINE,  bTagOutput, inOffset);

			inOffset = inMakeAmexEMVBatchData1(TAG_9F0D_IAC_DEFAULT, (unsigned char*) bTagOutput);
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_IAC_DEFAULT_LEN, (unsigned char*)&inOffset, sizeof(int));
			inStoreBatchFieldData ((BATCH_REC *)&pobTran->srBRec, FID_EMV_IAC_DEFAULT,  bTagOutput, inOffset);

/////////////////////////////////////////////////////////////////////////////////
	}
	LOG_PRINTFF((0x08L, "EMV_ADD_DATA_TO_BATCH = inEMVAddDataToBatch ==================== OK"));
	return VS_SUCCESS;
}


int inPrintWatchPacket(unsigned char *pucMessage, int inLen, char*szPrintBuffer)
{
    extern PRINTER_OBJECT obPrinter;
    char ucLineBuffer[24 + 1 + 1];
    unsigned char *pucBuff;
    int inBuffPtr = 0;

    if (inLen <= 0)
        return(VS_SUCCESS);

    p350ColumnMode(COLUMN_TYPE_24);

    shSpool(&obPrinter, "Printing Packets\n");
    shSpool(&obPrinter, "\n----\n");
    shSpool(&obPrinter, szPrintBuffer);
    shSpool(&obPrinter, "\n");

    pucBuff = pucMessage + inLen;


    while (pucBuff > pucMessage)
    {
        MEMCLR(ucLineBuffer, sizeof(ucLineBuffer));
        for (inBuffPtr = 0; (inBuffPtr < 24) && (pucBuff > pucMessage); inBuffPtr += 3)
        {
            sprintf(&ucLineBuffer[inBuffPtr], "%02X ", *pucMessage);
            pucMessage++;
        }

        ucLineBuffer[24] = '\n';
        shSpool(&obPrinter, ucLineBuffer);
     }

shSpool(&obPrinter, "\n----\n\n\n");
     return (VS_SUCCESS);
}



int inSetEMVScriptFile(char *pszFileName, unsigned char ucTag, char *pucScript, unsigned short usDataLen)
{
    int inResult;
    FHANDLE hFHandle;
    char ucBuffer[255];

    hFHandle = open(pszFileName, O_RDWR);
    if (hFHandle < 0)
    {
        if ((hFHandle = open(pszFileName, O_CREAT|O_RDWR)) < 0)
            return(VS_ERR);
    }

    ucBuffer[0] = ucTag;
    ucBuffer[1] = usDataLen;
    memcpy(&ucBuffer[2], pucScript, usDataLen);

    lseek(hFHandle, 0l, SEEK_END);
    inResult = write(hFHandle, ucBuffer, usDataLen + 2);

 	if (inResult != usDataLen + 2)              /* Error writing record info */
    {
        close(hFHandle);
    	return(VS_ERR);
   	}
    close(hFHandle);
    return(VS_SUCCESS);
}
//KiaSoon 070206: For those transactions do not require full emv transaction
int inEMVSetNonChip(TRANSACTION_OBJECT *pobTran)
{
	if(pobTran->inChipStatus == EMV_CARD)
	{
		pobTran->inChipStatus = EMV_EASY_ENTRY_CARD;
		pobTran->srBRec.inChipStatus = pobTran->inChipStatus;
	}
	return VS_SUCCESS;
}

int inUpdateReversalTVR(void) //edi
{
    char szReversalFileName[20];
	char szBackupReversalFileName[20];
	char szBuffer[1024];
	int i=0;
	int fhandle;
	int bytes;
	int inBufferSize = 0;
	int inOffset = 0;
	unsigned char bTagOutput[255];

	//Get Reversal File Name
	memset(szReversalFileName, 0x00, sizeof(szReversalFileName));   
	memset(szBackupReversalFileName, 0x00, sizeof(szBackupReversalFileName));
    vdGetReversalFileName(szReversalFileName, inGetHostIndex());
    sprintf(szBackupReversalFileName, "%s%s", szReversalFileName, BACKUP_REV_FILE_EXTN);
	
	//Read contain of reversal file, and save to szBuffer
	memset(szBuffer, 0x00, sizeof(szBuffer));
	fhandle = open(szBackupReversalFileName, O_RDWR);
	if (fhandle == -1) return 0;
	lseek(fhandle, 0L, SEEK_SET);
	for (i=0; ; i++){
		bytes = read(fhandle, (void *)&szBuffer[i], 1);
		if (bytes!=1) break;
	}
	if (i>0) inBufferSize = i-1;
	
	//Modify TVR if found
	for (i=inBufferSize-1; i>=0 ;i--){
		if (memcmp(&szBuffer[i], "\x95\x05", 2)==0){
			memset(bTagOutput, 0x00, sizeof(bTagOutput));
			inOffset = inMakeEMVBatchData(TAG_9500_TVR, (unsigned char*) bTagOutput);
			memcpy(&szBuffer[i], bTagOutput, 7);
			break;
		}
	}	

	for (i=inBufferSize-1; i>=0 ;i--){
		if (memcmp(&szBuffer[i], "\x9F\x10", 2)==0){
			memset(bTagOutput, 0x00, sizeof(bTagOutput));
			inOffset = inMakeEMVBatchData(TAG_9F10_ISSUER_APP_DATA, (unsigned char*) bTagOutput);
			memcpy(&szBuffer[i], bTagOutput, inOffset);
			break;
		}
	}	
	
	//Write to file
	lseek(fhandle, 0L, SEEK_SET);
	bytes = write(fhandle, szBuffer, inBufferSize);
	close(fhandle);
	return 1;
}


